我有以下LINQ查询:
var aKeyword = "ACT";
var results = from a in db.Activities
where a.Keywords.Split(',').Contains(aKeyword) == true
select a;
关键字是以逗号分隔的字段。
每次运行此查询时,都会出现以下错误:
“LINQ to Entities无法识别方法'Boolean Contains [String](System.Collections.Generic.IEnumerable`1 [System.String],System.String)'方法,而且此方法无法翻译进入商店表达。“
我想做什么的替代方案是什么?
答案 0 :(得分:8)
您的问题是LINQ-to-Entites必须将您提供的所有内容翻译成SQL以发送到数据库。
如果这确实是你需要做的,你将不得不强制LINQ-to-Entities拉回所有数据和LINQ-to-Objects来评估条件。
例如:
var aKeyword = "ACT";
var results = from a in db.Activities.ToList()
where a.Keywords.Split(',').Contains(aKeyword) == true
select a;
请注意,这将从“活动”表中撤回所有对象。另一种方法可能是让DB做一些初始过滤器,然后过滤剩下的部分:
var aKeyword = "ACT";
var results = (from a in db.Activities
where a.Keywords.Contains(aKeyword)
select a).ToList().Where(a => a.KeyWords.Split(',').Contains(aKeyword));
这将让LINQ-to-Entities执行它理解的过滤器(string.Contains变成类似的查询),它将过滤掉一些数据,然后在你拥有LINQ-to-Objects时应用你想要的真实过滤器物体回来了。 ToList()调用强制LINQ-to-Entities运行查询并构建对象,允许LINQ-to-Objects成为执行查询第二部分的引擎。
答案 1 :(得分:2)
响应您对大数据集的性能考虑:
您将在客户端上进行非索引通配符字符串匹配,所以是的,会有性能损失。
您是否有理由在一个表格字段中包含多个关键字?您可以将其标准化,以获得一个ActivityKeywords表,其中每个Activity都有许多关键字记录。
活动(activity_id,... / *删除关键字字段* /)---> ActivityKeywords(activity_id,keyword_id)--->关键字(keyword_id,value)
查看非首次常规表单:http://en.wikipedia.org/wiki/Database_normalization
编辑:即使你坚持使用一列,也有办法在服务器上做所有事情(如果你有严格的语法:'keyword1,keyword2,...,keywordN'):
var aKeyword = "ACT";
var results = (from a in db.Activities
where a.Keywords.Contains("," + aKeyword) || a.Keywords.Contains(aKeyword + ",")
select a;
答案 2 :(得分:0)
我的猜测就是你打电话给斯普利特。它应该采取一个数组。也许Linq中有另一个Split正在寻找并给你一个不寻常的错误:
这适用于Linq to Objects:
var dataStore = new List<string>
{
"foo,bar,zoo",
"yelp,foo",
"fred",
""
};
var results = from a in dataStore
where a.Split(new[] {','}).Contains("foo")
select a;
foreach (var result in results)
{
Console.WriteLine("Match: {0}", result);
}
输出以下内容:
Match: foo,bar,zoo
Match: yelp,foo
实际上,想一想,你是否需要拆分? a.Contains("foo")
对您来说可能已足够(除非您不想点击foobar
)。
答案 3 :(得分:0)
在过滤客户端之前,您可能希望look at this question about L2E and .Contains获得比在超集中猜测更有效的解决方案。