【问题标题】:Entity Framework: How to optimize this below linq query?实体框架:如何优化以下 linq 查询?
【发布时间】:2020-02-07 15:25:15
【问题描述】:

我需要一些关于如何改进以下查询的建议。

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)
};

Here School--> Teacher --> Fraction --> TestPRepetition --> InvoiceableItem 表之间的关系。

请建议我在哪里可以提高性能。这只会命中一次,所以我不能使用编译查询。没有用。

【问题讨论】:

    标签: c# .net performance linq entity-framework-6


    【解决方案1】:

    简单。不要加载所有数据。

    Teacher -> Fraction -> TestRPepetition 乘以您提取的 odf 数据量。

    Ef 的目的是提取你需要的数据,现在将大量相关数据加载到内存中,以防你有一天需要它。

    在这一刻提取您需要的最少数据量,当您需要更多时返回数据库。当您遇到问题时通过添加预加载从那里进行优化,但始终保持在您需要的最低限度。

    现在,您可以在特定代码中加载与所有 tacher 相关的所有数据。这可能是一个荒谬的数据量,主要是噪音,没有正确用于进一步处理。

    【讨论】:

    • 既然我已经选择并加载了只需要的列,那么教师的所有数据如何加载?你能举个例子如何只加载教师中的特定列吗?
    • 是的,不要加载它们。简单的。您将它们加载到 newTabularItem - 扔掉不需要的东西。
    【解决方案2】:

    有几个选项,但在 EF 中很少

    • 清理数据库中的空值
    • 将诸如 TeacherHasInvoicingInProgressInvoiceableItem 等隐含实体关系构建到数据库中(通过外键或映射表)
    • 预取重复语句,如 o.ActivityStatusesInternal.FirstOrDefault

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多