简体   繁体   English

实体框架:如何优化下面的 linq 查询?

[英]Entity Framework: How to optimize this below linq query?

I need some suggestions that how to improve this below query.我需要一些关于如何改进以下查询的建议。

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 relation between tables.这里 School--> Teacher --> Fraction --> TestPRepetition --> InvoiceableItem 表之间的关系。

please suggest me where i can improve performance.请建议我在哪里可以提高性能。 This will hit only once, so i cant use compiled query.这只会命中一次,所以我不能使用编译查询。 there is no use.没有用。

Simple.简单的。 DO not load all the data.不要加载所有数据。

Teacher -> Fraction -> TestRPepetition multiplies the amount odf data you pull.教师 -> 分数 -> TestRPepetition 乘以您提取的 odf 数据量。

Ef is meant to pull the data you need, now load a lot of related data into memory IN CASE YOU MAY NEED IT ONE DAY. Ef 旨在拉取您需要的数据,现在将大量相关数据加载到内存中,以防您有一天可能需要它。

Pull the minimum amount of data you need in this moment, go back to the database when you need more.拉取此时你需要的最少量数据,当你需要更多时回到数据库。 Optimize from there when you run into problems by adding preloads, but always keep to the minimum you need.当您遇到问题时,通过添加预加载进行优化,但始终保持在您需要的最低限度。

Right now you load all data related to all tachers within a specific code.现在,您可以在特定代码中加载与所有 tacher 相关的所有数据。 This is likely a ridiculous amount of data that mostly is noise and not properly used in further processing.这可能是大量的数据,主要是噪音,没有正确用于进一步处理。

There are a couple options, but few are in EF有几个选项,但在 EF 中很少

  • Clean up the null values in the database清理数据库中的空值
  • Build the implied entity relations like TeacherHasInvoicingInProgressInvoiceableItem into the database (via foreign key or mapping table)将TeacherHasInvoicingInProgressInvoiceableItem等隐含实体关系构建到数据库中(通过外键或映射表)
  • Prefetch repeat statements like o.ActivityStatusesInternal.FirstOrDefault预取重复语句,如 o.ActivityStatusesInternal.FirstOrDefault

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM