Reputation: 603
I'm trying to use Array.Contains on a string array within a Linq query:
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;
When the query is evaluated it crashes with "Unsupported overload used for query operator 'Contains'.
I tested this code using the StringComparer and it works fine and prints out "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());
Can anyone show me how to use a case insensitive Array.Contains within a Linq query? I do NOT want to convert the original string ToUpper() or ToLower() as it is expensive and it changes the original data.
Upvotes: 2
Views: 2488
Reputation: 49133
Your first snippet is invoked using Linq to SQL, this means that it will eventually be translated into SQL. So, whether comparison will be case-sensitive or not depends on the COLLATION
of your table column. That's why Linq throws the exception, because it cannot guarantee case-sensitivity.
Your second query snippet is performed using Linq to Objects, hence string equality can be enforced, since the actual string
is already in-memory.
Upvotes: 4
Reputation: 149608
I tested this code using the StringComparer and it works fine and prints out "fOO":
LINQ to Objects is different than LINQ to SQL/Entities. The latter needs to convert your query into a SQL expression, hence it doesn't understand what StringComparsion
is.
You can use AsEnumerable()
on your query to bring the data in-memory:
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()
Upvotes: 2