Останні 6 місяців я провів боротьбу з цим обмеженням за допомогою EF 3.5, і хоча я не найрозумніший чоловік у світі, я впевнений, що можу запропонувати щось корисне на цю тему.
SQL, згенерований вирощуванням 50-мильного дерева виразів "АБО стиль", призведе до поганого плану виконання запиту. Я маю справу з кількома мільйонами рядків, і вплив є значним.
Існує невеликий хак, який я знайшов, щоб зробити SQL "в", який допомагає, якщо ви просто шукаєте купу сутностей за ідентифікатором:
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. Ендрю Тапперт (Person) має дві посвідчення особи (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 всередині виразу.