Массив без учета регистра. Содержится в запросе Linq

Я пытаюсь использовать Array.Contains для строкового массива в запросе Linq:

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;

Когда запрос оценивается, он выдает сообщение "Неподдерживаемая перегрузка, используемая для оператора запроса" Содержит ".

Я проверил этот код с помощью 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());

Может кто-нибудь показать мне, как использовать без учета регистра Array.Contains в запросе Linq? Я не хочу конвертировать исходную строку ToUpper() или ToLower(), так как это дорого, и это изменяет исходные данные.

2 ответа

Ваш первый фрагмент вызывается с использованием Linq to SQL, это означает, что в конечном итоге он будет переведен в SQL. Итак, будет ли сравнение чувствительным к регистру или нет, зависит от COLLATION вашего столбца таблицы. Вот почему Linq выдает исключение, потому что он не может гарантировать чувствительность к регистру.

Ваш второй фрагмент запроса выполняется с использованием Linq to Objects, поэтому может быть обеспечено равенство строк, так как фактическое string уже в памяти.

Я проверил этот код с помощью 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()
Другие вопросы по тегам