Последние 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 внутри выражения.