[英]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.