【问题标题】:Entity Framework - Best practice to resolve performance issue with lazy loading实体框架 - 解决延迟加载性能问题的最佳实践
【发布时间】:2016-01-21 16:12:40
【问题描述】:

我接手了一个使用 Entity Framework 的项目。代码似乎分层良好,结构良好。问题是,正如我在 Entity Framework 中多次看到的那样,他们经常使用延迟加载。直到 db 得到一些数据并且 sql 查询刚刚达到峰值,问题才会出现。

该解决方案充分利用了将存储库保持小规模并仅获取一个级别的数据,并且当我处理一些最大的性能问题时,最常见的问题通常通过向存储库添加特定功能来加载嵌套实体并使用一些动态查询。

即GetCustomerWithOrderData,包括订单、订单行等。

有时我必须通过首先获取客户(包含关系)然后获取订单(包含)并通过 linq 将它们映射在一起来合并两个查询。

查询比示例复杂得多,延迟加载可能在业务层、控制器或视图中,因此需要跟踪解决很多问题。

但是我感觉代码挺大的,很难发现以后的问题。我现在需要的是一种跟踪延迟加载时间的好方法,并且还能够判断在特定调用中需要加载哪些对象。

如果我可以跟踪特定的操作调用,并获取执行的 sql、执行次数、加载时间等,那最好。

该解决方案是使用 MVC 3 和 EF4 构建的,升级到更新的 EF 是否可以获得任何性能?

【问题讨论】:

  • 你看过this很棒的文章吗?所以简而言之,从 ef 4 到 6 有 性能改进。

标签: c# entity-framework lazy-loading


【解决方案1】:

在之前的工作中,这成为了一个问题,因为开发人员会滥用框架并在各处创建n+1 问题——只有在表格变大时才会出现。另外,如果您没有将序列化深度指定为停止在 1,那么延迟加载也会产生 json 序列化问题——即使在这种情况下,有时相关对象会存在,而有时它们不会存在,这很奇怪(取决于深度)。

最后,我们完全关闭了延迟加载,并强制开发人员进行第二次数据库调用以获取他们想要的子实体。此外,团队被指示在开发过程中保持Sql Server Profiler 处于开启状态,以确保不会创建任何会影响性能的东西。

这种方法肯定也有缺点,例如额外的数据库往返行程、额外的代码行,以及新开发人员对团队普遍缺乏理解为什么我们会做这样的事情。一些人认为我们可以在查询中使用 Includes,但在某些时候,我们的存储库会因为这样做而变得臃肿,而且简单性/可读性也很重要。最后,性能问题不存在了,所以在我看来,杀死延迟加载的权衡是值得的。

这不是您所问问题的直接答案,但也许它会给您一些额外的见解。在您的情况下,我会观察 Profiler 以查看最严重的滥用行为发生在哪里,然后一次修复一个,直到您的性能再次可以接受为止。您可能会发现您的解决方法是做类似的事情,并完全消除延迟加载。

我很想看到这个问题的其他答案,因为我认为这是一个重要的话题。

【讨论】:

  • 加1使用Sql Server Profiler查看实际查询。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多