Case Insensitive Array.Contains in Linq Query

时间:2015-05-26 16:29:33

标签: c# linq linq-to-sql case-insensitive stringcomparer

我试图在Linq查询中的字符串数组上使用Array.Contains:

var otherMatchingDevices = from d in selectedDevices
                           from c in mldb.Companies
                           where d.CompanyID == c.CompanyID && c.Deleted == 0
                           where searchTerms.Contains(d.Name.ToString(), StringComparer.CurrentCultureIgnoreCase) || searchTerms.Contains(c.CompanyName.ToString(), StringComparer.CurrentCultureIgnoreCase)
                           select d;

当评估查询时,它会崩溃,并且#34;用于查询运算符的不支持的重载'包含'。

我使用StringComparer测试了这段代码,它工作正常并打印出来" fOO":

string[] sList = { "fOO", "bar" };
string[] array = { "foo" };
List<string> stringlist = sList.ToList();
var qry = from s in stringlist
          where array.Contains(s, StringComparer.CurrentCultureIgnoreCase)
          select s;
if (qry.Count() > 0) Console.WriteLine(qry.First().ToString());

有人能告诉我如何在Linq查询中使用不区分大小写的Array.Contains吗?我不想转换原始字符串ToUpper()或ToLower(),因为它很昂贵并且它会更改原始数据。

2 个答案:

答案 0 :(得分:4)

使用 Linq to SQL 调用您的第一个代码段,这意味着它最终会被转换为SQL。因此,比较是否区分大小写取决于表格列的COLLATION。这就是Linq抛出异常的原因,因为它不能保证区分大小写。

您的第二个查询代码段是使用 Linq to Objects 执行的,因此可以强制执行字符串相等,因为实际的string已经在内存中。

答案 1 :(得分:2)

  

我使用StringComparer测试了这段代码,它运行正常   打印出“fOO”:

LINQ to Objects与LINQ to SQL / Entities不同。后者需要将您的查询转换为SQL表达式,因此它不了解StringComparsion是什么。

您可以在查询中使用AsEnumerable()将数据带入内存:

var otherMatchingDevices = (from d in selectedDevices
                            from c in mldb.Companies
                            where d.CompanyID == c.CompanyID && c.Deleted == 0)
                            .AsEnumerable()
                            .Where(searchTerms.Contains(d.Name.ToString(), 
                                               StringComparer.CurrentCultureIgnoreCase) || 
                                   searchTerms.Contains(c.CompanyName.ToString(), 
                                               StringComparer.CurrentCultureIgnoreCase))
                            .ToArray()