Entity Framework поддерживает не все запросы. Это становится очевидным, если вы думаете о чем-то вроде следующего
dataContext.Persons.Where(person => MyMethod(person));
с MyMethod()
, возвращающим логическое значение. Метод может делать все, и вы не можете перевести все на SQL. Решение состоит в том, чтобы получить все объекты в локальную память, используя ToList()
, а затем использовать LINQ to Object.
dataContext.Persons.ToList().Where(person => MyMethod(person));
От вашего фактического запроса зависит, можно ли его переписать, чтобы он мог быть преобразован в SQL с помощью Entity Framework или если вам нужно выполнить запрос в локальной памяти, используя LINQ to Object.
Исключение, которое вы упомянули, звучит так, будто вы пытаетесь сделать что-то вроде следующего.
Company company = datacontext.Companies.Where(company.Name == "ACME").Single();
dataContext.Employees.Where(employee => employee.Company == company);
LINQ to Entity не поддерживает выражения, содержащие сущности, поэтому сравнение Company
сущностей недопустимо. В этом случае вы можете переписать его следующим образом.
dataContext.Employees.Where(employee => employee.Company.Id == company.Id);
При этом сравниваются только идентификаторы - примитивный тип, такой как целое число или GUID, - и его можно преобразовать в SQL.
Пример поиска слово за словом (см. Также комментарии)
IQueryable<People> result = entities.People;
foreach (String item in searchList)
{
// This copy is important in order not to modify the closure.
String itemCopy = item;
result = result.Where(p =>
p.FirstName.ToUpper().Contains(itemCopy) ||
p.LastName.ToUpper().Contains(itemCopy) ||
p.Phone.ToUpper().Contains(itemCopy));
}
Это создаст запрос слово за словом. Отмечено, что Entity Framework распознает ToUpper()
, ToLower()
и Contains()
(и некоторые другие) - поэтому я был строг, когда сказал, что Entity Framework не распознает вызовы методов. Да, но не много и не ToUpperInvariant()
и ToLowerInvariant()
. Кроме того, этот запрос преобразуется в CHARINDEX()
вызовов функций с использованием параметров сортировки столбца, поэтому поиск может выполняться без учета регистра без явных вызовов ToUpper()
или ToLower()
.