C# 不区分大小写的数组。包含在Linq查询中

C# 不区分大小写的数组。包含在Linq查询中,c#,linq,linq-to-sql,case-insensitive,stringcomparer,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

我正在尝试在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;
当对查询进行评估时,它会因“用于查询运算符“Contains”的不受支持的重载”而崩溃

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

string[]sList={“fOO”,“bar”};
字符串[]数组={“foo”};
List-stringlist=sList.ToList();
var qry=来自stringlist中的s
其中array.Contains(s,StringComparer.CurrentCultureInoRecase)
选择s;
if(qry.Count()>0)Console.WriteLine(qry.First().ToString());

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

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

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

我使用StringComparer测试了这段代码,它工作得很好 打印出“fOO”:

LINQ to Objects不同于LINQ to SQL/实体。后者需要将查询转换为SQL表达式,因此它不理解什么是
stringcomparison

您可以在查询中使用
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()

您使用的是LINQ2SQL还是LINQ2Entities?如果是,那么这就是它不受支持的原因。我编辑了您的标题。请参见“”,其中的共识是“不,它们不应该”。@MichaelDunlap使用Linq to SQL类。
ToUpper
可能没有那么贵,为什么您这么认为?@Magnus每次我们调用ToUpper()它创建了一个由GC创建和管理的临时字符串,这需要更多的时间和使用更多的内存。我也讨厌从数据库中的原始状态更改原始源数据,这让我感到困惑。如果要在内存中进行筛选(在这方面有一个大警告,因为它可能非常慢)我建议将
searchTerms
放入一个不区分大小写的hashset中
这里的代码不起作用,但答案很有用,我明白了基本想法,现在我明白了问题所在。感谢@MagnusThanks,这说明了为什么不能在Linq to SQL类上使用Contains方法,我也没有想到表的排序规则。感谢@haim770
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()