Последние 6 месяцев я боролся с этим ограничением с помощью EF 3.5, и хотя я не самый умный человек в мире, я почти уверен, что могу предложить что-то полезное по этой теме.
SQL, сгенерированный путем выращивания 50-мильного дерева выражений «стиль OR», приведет к плохому плану выполнения запроса. Я имею дело с несколькими миллионами строк, и влияние оказывается существенным.
Есть небольшой взлом, который я обнаружил, чтобы сделать 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 внутри выражения.