LINQ to Entities不能识别'System方法.String[]分裂(Char []) & # 39
本文关键字:分裂 Char String 方法 不能 Entities to 识别 System LINQ | 更新日期: 2023-09-27 18:05:37
我正试图实现一种方法,其中存储在数据库中的关键字用于活动(由逗号分割)匹配由逗号分割的给定字符串。
public List<TblActivities> SearchByMultipleKeyword(string keywords)
{
string[] keyword = keywords.Split(',');
var results = (from a in Entities.TblActivities
where a.Keywords.Split(',').Any(p => keyword.Contains(p))
select a).ToList();
return results;
}
我得到以下错误:
LINQ to Entities does not recognize the method 'System.String[] Split(Char[])' method,
and this method cannot be translated into a store expression.
如错误信息所示,使用实体框架不能这样做。
但是,还是有选择的
一个选项是实现,如果关键字存储为A,B,C,D
,则x
在那里,如果
a.Keywords.StartsWith(x + ",") ||
a.Keywords.Contains("," + x + ",") ||
a.Keywords.EndsWith("," + x)
如果x
本身不包含,
,则有效。缺点是,这将对表或包含Keywords
列的索引进行完全扫描。
另一种选择是规范化数据库。毕竟,活动和关键字之间是一对多的关系。然后这样建模:除了Activities
表(没有Keywords列)之外,还有一个KeyWords
表,它有两个列,一个活动表的外键和一个keyword
列。这将允许您在keyword
列上添加索引,这可以使查询超级快。
我重读了你的问题,并注意到你没有测试关键字相等,而只是Contains
。如果是这样,为什么不这样做呢?
a.Keywords.Contains(x)
是的,你可以这样做:
public List<TblActivities> SearchByMultipleKeyword(string keywords)
{
string[] keywordsSeparated = keywords.Split(',');
var results = (from a in Entities.TblActivities
where keywordsSeparated.Any(keyword => a.Keywords.Contains(keyword))
select a).ToList();
return results;
}
实体框架不支持String.Split
。这只是因为在SQL中没有相应的。
解决方案是:
- 在数据库中定义自定义函数本文提出了几种解决方案:http://sqlperformance.com/2012/07/t-sql-queries/split-strings
- 声明这个函数可以被LINQ使用
[EdmFunction]
属性的实体使用,就像这里解释的那样:如何从EF LINQ查询调用DB函数?
对于不涉及太多关键字和太多行的查询,您可以实现这个简单而快速的解决方案。您可以轻松地绕过Split函数,方法是重复修改结果,如下:
public List<TblActivities> SearchByMultipleKeyword(string keywords)
{
string[] keywords = pKeywords.Split(',');
var results = Entities.TblActivities.AsQueryable();
foreach(string k in keywords){
results = from a in results
where a.Keywords.Contains(k)
select a;
}
return results.ToList();
}
LINQ to Entities尝试将您的LINQ查询转换为SQL。因为它不知道如何在SQL查询中执行String.Split
,所以它失败了。
这意味着除非你想写一个String.Split
的SQL实现,你只能在LINQ对象中做,这意味着你需要首先将所有的数据加载到内存中,然后执行where
子句。一个简单的方法是使用.ToList()
:
var results = (from a in Entities.TblActivities select a).ToList(); //Results are now in memory
results = results.Where(a =>
a.Keywords.Split(',').Any(p => keyword.Contains(p))).ToList(); //This uses LINQ-to-objects
不确定,但可以试试:由于错误似乎是在寻找一个数组,这可能会起作用。
string[] keyword = keywords.Split(new char[] {','});
var results = (from a in Entities.TblActivities
where a.Keywords.Split(new char[] {','}).Any(p => keyword.Contains(p))
select a).ToList();