c# - Entity Framework 6 渴望加载具有许多子项和子项的大对象

标签 c# entity-framework asp.net-mvc-5 eager-loading

我正在将项目从延迟加载迁移到预加载。

我需要获取一个大对象及其所有子对象,将其序列化并发送到前端的 SPA 应用。

我构建了海量查询,但它占用了太多内存(如 VS 的数据诊断工具所示,内存使用量跳跃了 200mb,对象本身在序列化为 JSON 时约为 60KB)

Include(x => x.Privileges)
.Include(x => x.Team.Branch)
.Include(x => x.Equality)
.Include(x => x.AddressDetails).Include(x => x.ContactDetails)

.Include(x => x.EmployeeDetails.GeneralUnavailability)
.Include(x => x.EmployeeDetails.EligibilityDocuments.Select(z => z.Document.Priviliges))
.Include(x => x.EmployeeDetails.Position.PositionPayRuleExceptions).Include(x => x.EmployeeDetails.Position.PositionPayRuleExceptions.Select(z => z.PayRule)).Include(x => x.EmployeeDetails.Position.DefaultOffer)


.Include(x => x.TransportationMode.ProofOfLicence.Priviliges).Include(x => x.TransportationMode.ProofOfInsurance)

.Include(x => x.UserAcademicQualifications.Select(z => z.AcademicQualification)).Include(x => x.UserAcademicQualifications.Select(z => z.AcademicQualificationScan.Priviliges))

.Include(x => x.ProfessionalRegistrations.Select(z => z.Body)).Include(x => x.ProfessionalRegistrations.Select(z => z.ProfessionalRegistrationScan.Priviliges))
.Include(x => x.Unavailabilities.Select(z => z.AbsenceType)).Include(x => x.Unavailabilities.Select(z => z.Document.Priviliges))
.Where(x=>x.Id=1)

我不熟悉使用 ef6 进行查询...因为直到现在我都在使用延迟加载。有没有办法优化它?

权限是权限模型的列表

Document、ProfessionalRegistrationScan、AcademicQualificationScan、ProofOfInsurance、ProofOfLicence 正在使用具有多对多关系权限的文件模型。

谢谢你的帮助

更新

尝试使用 .AsNoTracking() 作为测试......并且内存使用量跳跃了 ~100mb。 这对于 ~60kb 的对象来说还是有点高...

最佳答案

好吧,数据就是数据。如果您确实需要所有这些,那么这很可能是您能做的最好的。显然,像您所做的那样预先加载和使用 AsNoTracking 会有所帮助。您实际上只能再看几样东西:

  1. 如果它是您可以“分页”的内容,使用 SkipTake 可以减少您必须一次检索的数据量。显然,您将在分页期间发出更多查询,但每个单独的查询都会更轻松,至少只根据用户的请求发生,而不是总是发生。例如,如果他们只关心结果的第一页,那么您永远不必获取所有其余数据。

  2. 明智地使用Select。如果您只需要某些列,则仅将这些列选择到其他 DTO 类或异常对象中将减轻查询的需求。

  3. 创建存储过程。如果您要查看 EF 生成的类似这样的查询,它可能会非常庞大​​。 EF 在优化查询方面做得相对较好,但由于连接如此之多,它的体积还是很大。然后,SQL Server 必须解析所有这些 SQL 并制定执行计划,然后才能实际运行查询并返回结果。存储过程消除了所有这些初始工作。

  4. 如果您无法真正进一步优化它并且您同时需要所有这些数据,那么您唯一的其他选择就是向您的数据库投入资源。确保它有足够的 RAM、足够的内核、快速的驱动器——最好是 SSD 等。还要确保你的网络服务器和数据库服务器之间的网络尽可能快。理想情况下,它们应该在同一个 LAN 上。如果您必须跨越防火墙等,那将大大降低速度。

关于c# - Entity Framework 6 渴望加载具有许多子项和子项的大对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45079165/

相关文章:

c# - 隐式与显式接口(interface)实现

c# - 在 Entity Framework 核心中合并迁移

c# - 未使用OWIN承载 token 对用户登录进行身份验证

c# - 多个独立的注册和登录表单 .NET Identity 2.0

c# - 在 C# 自动实现的属性中定义 <summary> 和 <value> 的目的是什么?

c# - 为 Acumatica 创建 TreeView

c# - CPU占用问题

c# - 需要为最大日期值构建表达式树

entity-framework - Doctrine 和多实体关联

c# - 在 Asp.net Core 中获取 UserManager 类的对象?