Медленный запрос с Entity Framework при использовании предиката Include with Func

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

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

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

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

t => t.id == myId

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

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

ОБНОВЛЕНИЕ-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 включается, и данные возвращаются мгновенно.

Правильно ли установлены внешние ключи между MyData, MoreData и EvenMoreData?

Risto M 26.03.2019 11:57

Обратите внимание, что это упрощенный пример, но внешние ключи установлены для некоторых таблиц, а не для всех.

Thierry 26.03.2019 12:05

Если у таблиц нет внешних ключей, как тогда можно присоединиться (что делает .Include)?

Risto M 26.03.2019 12:11

Я не уверен, но это определенно работает, просто медленно. Я обновлю свой ответ через секунду, так как нашел кое-что интересное, но пока не решение.

Thierry 26.03.2019 12:14

Без внешних ключей он не может ограничивать результаты соединения и извлекает все содержимое таблицы (450 КБ?) -> медленно

Risto M 26.03.2019 12:17

где ожидает Expression<Func<T,bool>>, так что, возможно, дополнительное преобразование заставляет его оценивать локально?

DevilSuichiro 26.03.2019 12:19

Возможно, я ошибаюсь насчет внешнего ключа, но не думаю. Как вы объясните комментарии из обновленного ответа

Thierry 26.03.2019 12:19

@DevilSuichiro После того, как я изменил это на выражение, мой запрос сократился с 29 секунд до менее 12 мс, что отлично, поскольку теперь он соответствующим образом фильтруется. Спасибо еще раз.

Thierry 26.03.2019 13:49
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
8
219
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

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

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

Другие вопросы по теме

Похожие вопросы

С# не может получить доступ к файлу сразу после его создания
Невозможно использовать тип в качестве параметра типа из-за отсутствия неявного преобразования ссылок
Как подключиться к локальной базе данных через Интернет с помощью браузера с другого компьютера?
Как найти или подсчитать дубликат в многомерном массиве в С#
Перенаправление HTTPS только для определенного порта (прослушивание смешанных портов) с Kestrel
Переопределение статуса выполнения теста для пользовательского исключения при использовании Specflow
Как исправить «System.InvalidOperationException: неверная попытка вызвать чтение, когда программа чтения закрыта» при вызове скомпилированного запроса
Получите 400 неверных запросов при вызове моего webapi
Обновить атрибут в списке объектов, используя другой список, используя Lambda C#
Программное создание диаграммы и установка ее легенд