我能做多次" .Contains"在单个Linq-to-SQL语句中进行测试?

时间:2015-01-28 14:45:07

标签: c# linq-to-sql

我要求返回与字符串列表中的一个匹配的所有项目。用户输入一个分号分隔的字符串列表:

  

ABC; MNO; XYZ

我需要返回所有产品代码(例如)包含“abc”或“mno”或“xyz”的项目。

我有以下代码适用于一个案例,正确返回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();

但是,在另一种情况下,我需要对列表进行后处理。这使用allItems作为另一个查询的输入之一。

当我在inputString中没有任何内容或只有一个条目时,后处理代码工作正常。但是,如果我有一个项目列表,我会收到以下异常:

  

不支持返回自引用常量表达式的IQueryable。

这是导致问题的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?

提出同样的问题,但接受的答案只是3 rd 派对工具包的链接。

我已经尝试了其他构造,包括现在CodeCaster建议的构造,并且他们给出相同的错误或者这个:

  

除了Contains运算符之外,本地序列不能用于查询运算符的LINQ to SQL实现。

供参考,代码为:

var result = allItems.Where(i => productCodes.Any(p => i.ProductCode.ToLower().Contains(p)));

1 个答案:

答案 0 :(得分:0)

不幸的是,基本的LINQ-to-SQL无法做到这一点。在另一个问题中已经接受的答案确实是正确的方法。

PredicateBuilder和上面提到的LINQKit是开源的,可以毫无问题地在您的项目中使用。它也可以NuGet package使用,这使您的项目中的使用更加简单。