Подтвердить что ты не робот

LINQ To SQL exception: Локальная последовательность не может использоваться в LINQ to SQL реализации операторов запроса, кроме оператора Содержит

Рассмотрим этот запрос LINQ To SQL. Цель состоит в том, чтобы взять строку [] условий поиска и применить термины к множеству разных полей в таблице SQL:

string[] searchTerms = new string[] {"hello","world","foo"};
List<Cust> = db.Custs.Where(c => 
   searchTerms.Any(st => st.Equals(c.Email))
|| searchTerms.Any(st => st.Equals(c.FirstName))
|| searchTerms.Any(st => st.Equals(c.LastName))
|| searchTerms.Any(st => st.Equals(c.City))
|| searchTerms.Any(st => st.Equals(c.Postal))
|| searchTerms.Any(st => st.Equals(c.Phone))
|| searchTerms.Any(st => c.AddressLine1.Contains(st))
)
.ToList();

Исправлено исключение:

Локальная последовательность не может использоваться в реализации операторов запросов LINQ to SQL, за исключением оператора Contains()

Вопрос: Почему возникает это исключение и как можно переписать запрос, чтобы избежать этого исключения?

4b9b3361

Ответ 1

Замените использование Any с Содержит в вашем запросе. например:

searchTerms.Contains(c.Email)

Это должно получить результат, который вы ищете. Он выглядит обратным, но он правильный: он будет генерировать оператор IN для каждого поля внутри Содержит со всеми элементами в searchTerms.

Часть AddressLine1 не будет работать таким образом - вам придется циклически генерировать сравнения самостоятельно с помощью

c.addressLine1.Contains(...)

Что-то вроде PredicateBuilder может быть полезно для этого.

Ответ 2

Просто мысль (не связанная напрямую с вопросом, но она может помочь другим зрителям):

Я получал то же сообщение об ошибке, что и вы, хотя я правильно использовал метод Contains(), и мне потребовалось некоторое время, чтобы понять, что корень моей проблемы возвращает IEnumerable к чему-то, что необходимо для далее фильтровать результаты запроса L2S. Как только я изменил тип возвращаемой функции на IQueryable, проблема исчезла. Это имеет смысл, поскольку IEnumerable не может быть далее отфильтрован, но IQueryable может.

Ответ 3

Я получал ту же ошибку, но ни одно из вышеперечисленных решений не работало для меня.

Что сработало для меня, так это сделать db.Custs в список first, так:

List<Cust> =db.Custs.ToList<Cust>.Where(...

Я понятия не имею, почему это сработало, но так оно и было.

Ответ 4

По сути, ошибка говорит о том, что вы выполняете объединение между двумя коллекциями, одна из которых является таблицей базы данных, а другая - массивом. LINQ не предназначен для обработки этого - либо оба должны быть в базе данных, либо оба в памяти (со специальным исключением, созданным при использовании Contains)