我可以在单个 Linq-to-SQL 语句中执行多个“.Contains”测试吗?
Can I do multiple ".Contains" tests in a single Linq-to-SQL statement?
我需要 return 所有匹配字符串列表之一的项目。用户输入以分号分隔的字符串列表:
abc; mno; xyz
我需要 return 产品代码(例如)包含 "abc" OR "mno" OR "xyz".
的所有项目
我有以下适用于一种情况的代码,正确 returning allItems
中的预期项目:
IQueryable<Items> allItems = FindItemsBasedOnSomeOtherCriteria();
var productCodes = inputString.Split(new char[] { ';', ',' }, StringSplitOptions.RemoveEmptyEntries);
IEnumerable<Item> results = null;
foreach (var productCode in productCodes)
{
var query = allItems.Where(i => i.ProductCode.ToLower().Contains(productCode.ToLower()));
if (results == null)
{
results = query;
}
else
{
results = results.Union(query);
}
}
allItems = results.AsQueryable();
然而,在另一种情况下,我需要post-处理列表。这使用 allItems
作为另一个查询的输入之一。
当我在 inputString
中什么都没有或只有一个条目时,post 处理代码工作正常。但是,如果我有一个项目列表,我会引发以下异常:
An IQueryable that returns a self-referencing Constant expression is not supported.
导致问题的是 Union
语句。那么如何重写上面的循环使其不需要它呢?
理想情况下,我希望能够编写如下内容:
var productCodes = inputString.ToLower().Split(new char[] { ';', ',' }, StringSplitOptions.RemoveEmptyEntries);
var query = allItems.Where(i => productCodes.InverseContains(i.ProductCode.ToLower()));
但这不存在。
搜索抛出了这个问题:
Linq-to-SQL: Combining (OR'ing) multiple "Contains" filters?
问的是同样的问题,但接受的答案只是 link 到第 3rd 方工具包。
我已经尝试过其他构造,包括现在由 CodeCaster 建议的构造,但它们要么给出相同的错误,要么给出这个:
Local sequence cannot be used in LINQ to SQL implementations of query operators except the Contains operator.
供参考,代码为:
var result = allItems.Where(i => productCodes.Any(p => i.ProductCode.ToLower().Contains(p)));
不幸的是,这对于基本的 LINQ-to-SQL 是不可能的。另一个问题中已经接受的答案确实是正确的做法。
PredicateBuilder 和提到的 LINQKit 是开源的,可以在您的项目中简单地使用而不会出现任何问题。它也可以作为 NuGet package 使用,这使得您的项目中的使用更加简单。
我需要 return 所有匹配字符串列表之一的项目。用户输入以分号分隔的字符串列表:
abc; mno; xyz
我需要 return 产品代码(例如)包含 "abc" OR "mno" OR "xyz".
的所有项目我有以下适用于一种情况的代码,正确 returning allItems
中的预期项目:
IQueryable<Items> allItems = FindItemsBasedOnSomeOtherCriteria();
var productCodes = inputString.Split(new char[] { ';', ',' }, StringSplitOptions.RemoveEmptyEntries);
IEnumerable<Item> results = null;
foreach (var productCode in productCodes)
{
var query = allItems.Where(i => i.ProductCode.ToLower().Contains(productCode.ToLower()));
if (results == null)
{
results = query;
}
else
{
results = results.Union(query);
}
}
allItems = results.AsQueryable();
然而,在另一种情况下,我需要post-处理列表。这使用 allItems
作为另一个查询的输入之一。
当我在 inputString
中什么都没有或只有一个条目时,post 处理代码工作正常。但是,如果我有一个项目列表,我会引发以下异常:
An IQueryable that returns a self-referencing Constant expression is not supported.
导致问题的是 Union
语句。那么如何重写上面的循环使其不需要它呢?
理想情况下,我希望能够编写如下内容:
var productCodes = inputString.ToLower().Split(new char[] { ';', ',' }, StringSplitOptions.RemoveEmptyEntries);
var query = allItems.Where(i => productCodes.InverseContains(i.ProductCode.ToLower()));
但这不存在。
搜索抛出了这个问题:
Linq-to-SQL: Combining (OR'ing) multiple "Contains" filters?
问的是同样的问题,但接受的答案只是 link 到第 3rd 方工具包。
我已经尝试过其他构造,包括现在由 CodeCaster 建议的构造,但它们要么给出相同的错误,要么给出这个:
Local sequence cannot be used in LINQ to SQL implementations of query operators except the Contains operator.
供参考,代码为:
var result = allItems.Where(i => productCodes.Any(p => i.ProductCode.ToLower().Contains(p)));
不幸的是,这对于基本的 LINQ-to-SQL 是不可能的。另一个问题中已经接受的答案确实是正确的做法。
PredicateBuilder 和提到的 LINQKit 是开源的,可以在您的项目中简单地使用而不会出现任何问题。它也可以作为 NuGet package 使用,这使得您的项目中的使用更加简单。