0

我有问题linq..

让我们看看代码

我有一个文章类:

public calss Article
{
    public string Tag{get; set; }
}

我保存用,逗号分隔的文章的每个标签。

例如 :first,second,third

当我想获得一篇文章时,我想获得具有任何共同标签的文章。

我使用这个查询但是:

var relatedArticles = 
        _db.Articles.Where(a => a.Tag
                                 .Split('،')
                                 .Any(t => article.Tag
                                                  .Split('،')
                                                  .Any(ac => ac == t)));

我得到了这个例外:

LINQ to Entities 无法识别方法 'System.String[] Split(Char[])' 方法

还有什么办法吗?

更新:我不能将标签保留在不同的表格中,因为我必须让用户在插入文章时创建任意数量的标签。像 50 并且在将文章保存到数据库时检查该标签是否存在将是开销。

4

5 回答 5

1

我认为我的评论可能值得作为您问题的答案,所以我把它写下来:)

你应该考虑你的表/类设计。

您需要对其进行规范化,因为它看起来像 n:m 参考。将文章保存在一个引用映射表的表中,在该表中引用 arcticleId 和 tagId,而不是一个带有主键 tagId 的标签的表。如果将来某个标签发生更改,您无需更新每篇文章,只需更新该特定标签,每篇文章都会更改。

于 2013-11-05T08:59:23.397 回答
1

如下设置你的类:

public class Article
{
    public List<string> Tag{get; set; }
}

我不是 100% 确定您的第二条语句做了什么,但您可以使用 a.Tag.Contains() 来检查您的值。

于 2013-11-05T08:30:59.363 回答
0

这意味着 Linq to entity 找不到可以写为 SQL 查询的拆分方法的翻译。如果要执行拆分功能,则必须通过调用等将记录带入ToList()内存AsEnumerable()

但更好的方法是为您的数据库中的标签创建单独的表。

Linq 查询看起来像这样(假设文章和标签之间存在多对多关系):

var relatedArticles = 
        _db.Articles.Where(a => a.Tags.Any(t => t.Articles.Count() > 1));
// if Article has Tag which is assigned more then to one Article then it suits us
于 2013-11-05T08:30:13.393 回答
0

“a.Tag.Split('،')”是 IQueryable 所在的表达式树中的一个节点,而不是实际操作。当您通过调用 ToList 之类的方法实现结果时,整个表达式树在执行之前会被转换为 SQL 表达式 - 这是错误点,因为翻译器不知道如何将 Split() 方法转换为 sql 语句。
作为替代方案,您可以将所有结果检索到应用程序中,通过 ToList() 将它们具体化,然后将它们作为 IEnumerables 执行您想要的操作。此外,您可以编写一个存储过程并将搜索标签数组传递到那里。
此外,也许它会起作用 - 尝试将一个简单的值数组(不是作为方法)传递给查询,因此生成的 sql 看起来像

"WHERE ... IN ...".
于 2013-11-05T08:31:02.727 回答
0

使用 EF 时,您不能像string.Split()直接在 Linq 中那样调用常规方法,因为它无法转换为 SQL。

您可以附加AsEnumerable()到您的Where()子句以使 Linq 获取数据,从而允许您稍后对其执行类似的操作。不幸的是,这将不允许您在不获取整个列表的情况下对列表执行您想要的操作,我相信您宁愿避免这样做。

也许你可以做这样的事情呢?:

 List<string> tagsForCurrentArticle = ... // fetch this first somehow

 _db.Articles.Where(a =>  
                      tagsForCurrentArticle.Any(tag => 
                                                   a.Tag.Contains(tag)))

请注意,要明确一点:这应该可行,但如果可能的话,更好的选择是将您的标签移到单独的表格中,正如其他人所建议的那样。

于 2013-11-05T08:38:22.910 回答