У меня есть коллекция (локальный массив, заполненный откуда-то еще) с набором Section
и Lines
. Это НЕ первичные ключи.
Скажите что-нибудь вроде этого:
class SectionLine {
int Section { get; }
int Line { get; }
}
class MyEntity {
int EntityId { get; set; }
int Section { get; set; }
int Line { get; set; }
string OtherProperty { get, set; }
// Many other options...
}
// ...
SectionLine[] allSectionLines = new [] { new SectionLine { Section = 5, Line = 2 }, new SectionLine { Section = 5, Line = 3 }, // etc.
Итак, я хочу отфильтровать свою коллекцию в DbContext для тех, которые соответствуют -both- section и line из любого в array allSectionLines
.
Обратите внимание, что Section
и Line
на объекте MyEntity
не являются первичными ключами, но они do имеют многостолбцовый индекс, что было бы здорово если бы его можно было использовать.
Я вижу пару вариантов, но мне не нравятся ... а именно:
- Несколько запросов, по одному для каждого элемента в
allSectionLines
. Этот массив поступает из другого источника (это не code-stati c) и может содержать много элементов, поэтому мне это не нравится. Изменить: это также относится к созданию составного предиката с множеством предложений OR
... если число в коллекции массивов достаточно велико, я уверен, что это будет работать довольно плохо - Создание одного свойства из мультисвойства, например:
var sectionLines = allSectionsLines.Select(x => x.Section + "-" + x.Line);
var myQuery = _dbContext.MyEntities.Where(x => sectionLines.Contains(x.Section + "-" + x.Line));
Это работает, но выполняет полное сканирование таблицы и не учитывает индекс, поэтому я бы предпочел избегайте этого
- Создайте хранимую процедуру в базе данных и выполните несколько соединений по нескольким столбцам, сначала вставив массив во временную таблицу (или передав эту таблицу в качестве параметра): это определенно работает, но эта база данных управляется кем-то другим, и я не выполняю никаких миграций. Я мог бы определенно попросить, чтобы SP был там ... но если это можно решить с помощью кода, я бы предпочел сделать это, не "касаясь" схемы базы данных.
делаем сейчас (проецируем объекты в простой DTO-подобный тип только с идентификатором, разделом и строкой, затем фильтруем в памяти и получаем идентификаторы, затем снова запрашиваем эти идентификаторы). Это работает ТОЛЬКО из-за имеющихся данных, доступной памяти и скорости реального сервера, но мне это не нравится .
Есть ли другой способ, которым я не нашел выполнение такого запроса, предпочтительно непосредственно в Entity Framework, которая не тратит впустую память, лишние «кажущиеся ненужными» запросы и может использовать индексы в базе данных вместо выполнения полного сканирования?
Это EF Core 3.1
Дополнение: Моя текущая мысль заключается в добавлении вычисляемого поля (с индексом) для строки «Section-Line» и выполнении запроса там ... снова, я не владелец базы данных, поэтому я бы предпочел не «просить об этом» ... но если это единственный способ, которым я действительно могу это сделать. Дело не в том, что это неразрешимо ... Я просто оцениваю альтернативы и смотрю, не упускаю ли я очевидную