Entity Framework: Как оптимизировать этот запрос linq ниже? - PullRequest
0 голосов
/ 07 февраля 2020

Мне нужны предложения по улучшению этого запроса ниже.

from o in this.DbContext.Set<School>().AsNoTracking()
from s in o.Teachers.DefaultIfEmpty()
where SchoolCodes.Contains(o.Code)
select new TabularItem
{
    SchoolId = o.Id,
    SchoolCode = o.Code,
    SchoolPurchaseOrderReference = o.PurchaseOrderReference,
    SchoolDescription = o.OrderDescription,
    SchoolActivityStatus = o.ActivityStatusesInternal.FirstOrDefault(os => os.ActivityName == orderLoggingActivity),
    Type = o.TypesAsString,
    CustomerCode = o.CustomerCode,
    TeacherId = s == null ? (Guid?)null : s.Id,
    TeacherCode = s == null ? null : s.Code,
    TeacherCustomerReference = s == null ? null : s.CustomerReference,
    TeacherIsImported = s == null ? (bool?)null : s.IsImported,
    TeacherIsRegisteredUnderModification = s == null ? (bool?)null : s.IsRegisteredUnderModification,
    TeacherStatus = s == null ? null : s.StatusAsString,
    TeacherStatusChangeDate = s == null ? (DateTimeOffset?)null : s.StatusChangeDate,
    IsReportInProgress = s == null ? false : s.IsReportInProgress,
    TeacherActivityStatus = s == null ? null : s.ActivityStatusesInternal.FirstOrDefault(ss => ss.ActivityName == orderLoggingActivity),
    TeacherHasUnresolvedIssue = s.TeacherIssuesInternal.Any(si => unresolvedIssueStatuses.Contains(si.StatusAsString)),
    TeacherHasAdvancePaymentInProgressInvoiceableItem = s.FractionsInternal.SelectMany(x => x.TestPRepetitionsInternal).Any(x => x.InvoiceableItem.IsAdvancePaymentInProgress),
    TeacherHasInvoicingInProgressInvoiceableItem = s.FractionsInternal.SelectMany(x => x.TestPRepetitionsInternal).Any(x => x.InvoiceableItem.IsInvoicingInProgress && x.InvoiceableItem.InvoicingStatusAsString != doNotInvoiceStatus),
    HasSchoolBasedInvoiceableItems = s.School.InvoiceableItemsInternal.Any(item => item.InvoicingStatusAsString != orderBasedInvoiceableItemStatus),
    SchoolHasInvoicingInProgressInvoiceableItem = s.School.InvoiceableItemsInternal.Any(x => x.IsInvoicingInProgress && x.InvoicingStatusAsString != doNotInvoiceStatus)
};

Здесь школа -> Учитель -> Фракция -> TestPRepetition -> InvoiceableItem отношение между таблицами.

пожалуйста, подскажите, где я могу улучшить производительность. Это произойдет только один раз, поэтому я не могу использовать скомпилированный запрос. нет смысла.

Ответы [ 2 ]

1 голос
/ 07 февраля 2020

Simple. НЕ загружайте все данные.

Учитель -> Фракция -> TestRPepetition умножает количество извлекаемых вами odf-данных.

Ef предназначен для извлечения нужных вам данных, теперь загружается много связанных данные в память на тот случай, если вам может понадобиться один день.

Потяните минимальный объем данных, который вам нужен в данный момент, go обратно в базу данных, когда вам нужно больше. Оптимизируйте оттуда, когда вы столкнетесь с проблемами, добавив предварительные загрузки, но всегда придерживайтесь минимума, который вам нужен.

Прямо сейчас вы загружаете все данные, относящиеся ко всем тахерам, в указанном c коде. Вероятно, это нелепое количество данных, которые в основном представляют собой шум и не используются должным образом при дальнейшей обработке.

0 голосов
/ 07 февраля 2020

Есть несколько вариантов, но немногие из них в EF

  • Очистка нулевых значений в базе данных
  • Встраивание подразумеваемых отношений сущностей, таких как TeacherHasInvoicingInProgressInvoiceableItem, в базу данных (через сторонний интерфейс) ключ или таблица сопоставления)
  • Предварительная выборка повторяющихся операторов, таких как o.ActivityStatusesInternal.FirstOrDefault
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...