繁体   English   中英

实体框架和linq字符串比较问题

[英]Entity framework and linq string comparsion issue

我有问题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一样,在将文章保存到db时检查该标记是否存在将是开销。

按如下方式设置您的课程:

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

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

我认为我的评论可能值得回答你的问题,所以我把它写成一个:)

你应该考虑你的桌子/班级设计。

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

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

但更好的方法是在db中为标记创建单独的表。

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

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

"WHERE ... IN ...".

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM