Где с Содержит в нескольких свойствах - PullRequest
1 голос
/ 14 июля 2020

У меня есть коллекция (локальный массив, заполненный откуда-то еще) с набором 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» и выполнении запроса там ... снова, я не владелец базы данных, поэтому я бы предпочел не «просить об этом» ... но если это единственный способ, которым я действительно могу это сделать. Дело не в том, что это неразрешимо ... Я просто оцениваю альтернативы и смотрю, не упускаю ли я очевидную

...