Почему я получаю ошибку:
Невозможно создать постоянное значение типа «Тип закрытия». В этом контексте поддерживаются только примитивные типы (например, 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, не так ли? Какие-либо предложения?
источник
Последние 6 месяцев я боролся с этим ограничением с помощью EF 3.5, и хотя я не самый умный человек в мире, я почти уверен, что у меня есть что-то полезное по этой теме.
SQL, сгенерированный путем выращивания дерева выражений в стиле «ИЛИ» высотой 50 миль, приведет к плохому плану выполнения запроса. Я имею дело с несколькими миллионами строк, и это оказывает существенное влияние.
Есть небольшой прием, который я нашел для выполнения SQL "in", который помогает, если вы просто ищете группу сущностей по идентификатору:
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 внутри выражения.
источник
Я нашел причину ошибки (я использую Framework 4.5). Проблема в том, что EF - сложный тип, который передается в параметре «Содержит», не может быть преобразован в запрос SQL. EF может использовать в запросе SQL только простые типы, такие как int, string ...
this.GetAll().Where(p => !assignedFunctions.Contains(p))
GetAll предоставляет список объектов сложного типа (например, «Функция»). Поэтому я бы попытался получить здесь экземпляр этого сложного типа в моем SQL-запросе, который, естественно, не может работать!
Если я могу извлечь из своего списка параметры, которые подходят для моего поиска, я могу использовать:
var idList = assignedFunctions.Select(f => f.FunctionId); this.GetAll().Where(p => !idList.Contains(p.FunktionId))
Теперь у EF больше нет сложного типа «Функция» для работы, но, например, с простым типом (длинным). И это прекрасно работает!
источник
Я получил это сообщение об ошибке, когда мой объект массива, используемый в функции .All, имеет значение null. После инициализации объекта массива (в вашем случае upperSearchList) ошибка исчезла. В этом случае сообщение об ошибке вводило в заблуждение.
где upperSearchList.All (arg => person.someproperty.StartsWith (arg)))
источник