LINQ to Entities:为什么我不能使用Split方法作为条件?

时间:2009-08-30 19:36:28

标签: .net linq linq-to-entities string-split

我有以下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)'方法,而且此方法无法翻译进入商店表达。“

我想做什么的替代方案是什么?

4 个答案:

答案 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获得比在超集中猜测更有效的解决方案。