Указанное вами выражение linq и сгенерированный SQL не совпадают.Например, выражение linq выполняет Include
для различных связанных таблиц, которые включали бы все те столбцы сущностей в SELECT верхнего уровня, которых нет в вашем примере SQL.Я также не вижу условий в выражении Linq для Take 500 & OrderBy или утверждении IsActive при записи.
Чтобы помочь определить источник любой проблемы с производительностью, нам нужно увидеть полное выражение Linq и полученный SQL.
Рассматривая основание предоставленного вами выражения Linq:
records = records
.Include(r => r.Employer)
.Include(r => r.Contractor)
.Include(r => r.RecordProducts)
.ThenInclude(rp => rp.ProductDefendant.Defendant)
.Where(r => EF.Functions.Like(r.Employer.DefendantCode, "%" + input.DefendantCode + "%")
|| EF.Functions.Like(r.Contractor.DefendantCode, "%" + input.DefendantCode + "%")
|| r.RecordProducts.Any(rp => EF.Functions.Like(rp.ProductDefendant.Defendant.DefendantCode, "%" + input.DefendantCode + "%") && rp.IsActive == true));
Есть несколько предложений, которые я могу сделать:
- Нет необходимости в
Functions.Like
.Вы должны быть в состоянии достичь того же с помощью Contains
. - Избегайте использования
Include
и вместо этого используйте Select
для извлечения столбцов из результирующей структуры, которая вам действительно нужна.Заполните их в ViewModels или используйте их в коде.Чем меньше данных вы извлекаете, тем лучше оптимизируется SQL для индексации и тем меньше данных передается по проводам.Потребление объектов также приводит к неожиданным сценариям с отложенной загрузкой, когда системы становятся более зрелыми, и кто-то забывает Include
новое отношение.
.
records = records
.Where(r => r.IsActive
&& (r.Employer.DefendantCode.Contains(input.DefendantCode)
|| r.Contractor.DefendantCode.Contains(input.DefendantCode)
|| r.RecordProducts.Any(rp => rp.IsActive
&& rp.ProductDefendant.Defendant.DefendantCode.Contains(input.DefendantCode))
.OrderBy(r => r.SourceCode)
.Select(r => new RecordViewModel
{
// Populate the data you want here.
}).Take(500).ToList();
Это также добавляет проверку IsActive,OrderBy
и Take(500)
на основе вашего примера SQL.