Entity Framework - ошибка «Невозможно создать постоянное значение типа« Тип закрытия »...»

entity-framework linq

Вопрос

Почему я получаю ошибку:

Невозможно создать постоянное значение типа «Тип закрытия». В этом контексте поддерживаются только примитивные типы (например, Int32, String и Guid).

Когда я пытаюсь перечислить следующий запрос Linq?

IEnumerable<string> searchList = GetSearchList();
using (HREntities entities = new HREntities())
{
   var myList = from person in entities.vSearchPeople
   where upperSearchList.All( (person.FirstName + person.LastName) .Contains).ToList();
}

Обновление : если я попробую следующее, просто чтобы попытаться изолировать проблему, я получу ту же ошибку:

where upperSearchList.All(arg => arg == arg) 

Похоже, проблема в методе All, верно? Какие-либо предложения?

Принятый ответ

Похоже, вы пытаетесь сделать эквивалент условия "ГДЕ ... В". Посмотрите, как писать запросы в стиле «WHERE IN» с использованием LINQ to Entities, чтобы узнать, как выполнить этот тип запроса с LINQ to Entities.

Также, я думаю, что сообщение об ошибке особенно бесполезно в этом случае, потому что .Contains не сопровождается скобками, что заставляет компилятор распознавать весь предикат как лямбда-выражение.


Популярные ответы

Последние 6 месяцев я боролся с этим ограничением с помощью EF 3.5, и хотя я не самый умный человек в мире, я почти уверен, что могу предложить что-то полезное по этой теме.

SQL, генерируемый ростом дерева выражений «OR style» высотой 50 миль, приведет к плохому плану выполнения запроса. Я имею дело с несколькими миллионами строк, и влияние является существенным.

Я обнаружил, что есть небольшой хак для выполнения SQL «in», который помогает, если вы просто ищете группу сущностей по id:

private IEnumerable<Entity1> getByIds(IEnumerable<int> ids)
{
    string idList = string.Join(",", ids.ToList().ConvertAll<string>(id => id.ToString()).ToArray());
    return dbContext.Entity1.Where("it.pkIDColumn IN {" + idList + "}");
}

где pkIDColumn - это имя столбца идентификатора первичного ключа вашей таблицы Entity1.

НО ПРОЧИТАЙТЕ!

Это нормально, но требует, чтобы у меня уже были идентификаторы того, что мне нужно найти. Иногда я просто хочу, чтобы мои выражения проникли в другие отношения, и у меня есть критерии для этих связанных отношений.

Если бы у меня было больше времени, я бы попытался представить это визуально, но я бы не просто изучил это предложение на мгновение: рассмотрим схему с таблицами Person, GovernmentId и GovernmentIdType. Эндрю Тапперт (Персона) имеет две идентификационные карты (GovernmentId), одну из Орегона (GovernmentIdType) и одну из Вашингтона (GovernmentIdType).

Теперь сгенерируйте из него edmx.

Теперь представьте, что вы хотите найти всех людей, имеющих определенное значение идентификатора, скажем, 1234567.

Это может быть достигнуто одним попаданием в базу данных:

dbContext context = new dbContext();
string idValue = "1234567";
Expression<Func<Person,bool>> expr =
    person => person.GovernmentID.Any(gid => gid.gi_value.Contains(idValue));

IEnumerable<Person> people = context.Person.AsQueryable().Where(expr);

Вы видите подзапрос здесь? Сгенерированный sql будет использовать «соединения» вместо подзапросов, но эффект тот же. В наши дни SQL-сервер в любом случае оптимизирует подзапросы в объединения под покровом, но в любом случае ...

Ключом к этой работе является .Any внутри выражения.



Related

Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow