实体框架 - 通过延迟加载解决性能问题的最佳实践

时间:2016-01-21 16:12:41

标签: c# entity-framework lazy-loading

我接管了一个包含Entity Framework的项目。代码看起来很好,并且具有良好的结构。问题是因为我已经多次看到Entity Framework,他们使用了懒惰加载。在db获取一些数据并且sql查询达到峰值之前,这些问题并不存在。

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

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

有时我必须先合并两个查询,首先获取Customer(包含关系),然后获取Orders(包括在内)并通过linq将它们映射到一起。

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

但我觉得代码很大,我很难找到未来的问题。我现在需要的是一种跟踪延迟加载的好方法,并且能够告诉特定呼叫需要加载哪些对象。

最好的方法是,如果我可以跟踪特定的动作调用,并获取执行的sql,多少次,加载时间等。

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

1 个答案:

答案 0 :(得分:1)

在之前的工作中,这成为一个问题,因为开发人员会滥用框架并在整个地方创建n+1个问题 - 只有在表格变得越来越大时才表现出来。如果你没有指定序列化深度停止在1,那么延迟加载也会产生json序列化的问题 - 即使在某种情况下,有时相关的对象会在那里很奇怪,有时它们也不会#39 ; t(取决于深度)。

最后,我们完全关闭了延迟加载,并强制开发人员进行第二次数据库调用以获取他们想要的子实体。此外,团队还被指示在开发过程中离开Sql Server Profiler,以确保不会产生任何会破坏性能的内容。

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

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

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