Медленный запрос с Entity Framework при использовании предиката «Включить с Func» - PullRequest
0 голосов
/ 26 марта 2019

Может кто-нибудь подсказать, пожалуйста, как включить предложение where в запрос linq to sql при использовании платформы сущностей с include

У меня есть следующий запрос:

var test = this.MyContext.MyData
           .Include("MoreData")
           .Include("EvenMoreData")
           .Where(predicate)

Где предикат определяется следующим образом:

t => t.id == myId

Проблема заключается в том, что он, кажется, не включает предложение Where в запрос SQL, когда я проверяю его через SQL Server Profiler, что приводит к очень медленному запросу, так как он возвращает 450k + записей вместо 7 в моем конкретном пример.

Любые идеи о том, как я могу включить предложение where в запрос, сгенерированный EF.

UPDATE-1:

Странно, но при замене предиката переменная устанавливается следующим образом:

private MyObject Get(Func<MyObject, bool> predicate)

...

this.UnitOfWork.MyObject.Get(t=>t.id == myId);

по

var test = this.MyContext.MyData
       .Include("MoreData")
       .Include("EvenMoreData")
       .Where(t=>t.id = 1234)

Оператор where включается и данные возвращаются мгновенно.

1 Ответ

1 голос
/ 26 марта 2019

Как уже упоминалось в комментариях:

.Where () ожидает Expression<Func<T,bool>>, тогда как ваш предикат имеет тип Func<T,bool>. Это (предположительно) запрещает EF преобразовывать его в SQL-запрос, то есть он будет оцениваться локально (в базовой реализации ICollection).

В этом примечании обратите внимание, что условия WHERE для .Include не работают так, как вы, вероятно, ожидали, поскольку сгенерированный SQL объединит две сопоставленные таблицы и оценит условие в таблице результатов, а не объединит сопоставленная таблица с сокращенным набором результатов второй таблицы. Причина, по которой этот запрос выполняется быстрее: 1. DBS может использовать индексы из-за условия и 2. количество строк, которые должны быть материализованы, меньше.

...