简体   繁体   English

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

[英]Entity Framework - Best practice to resolve performance issue with lazy loading

I've taken over a project with Entity Framework. 我已经用Entity Framework接管了一个项目。 The code seems to be good layered and done with good structure. 该代码似乎具有良好的层次结构,并且结构良好。 The problem is as I've seen many times with Entity Framework, that they used lazy loading alot. 问题是,正如我在Entity Framework中看到的很多次一样, 他们大量使用了延迟加载。 The problems don't apear until the db got some data and the sql queries just peaks. 直到数据库获得一些数据并且sql查询达到峰值后,问题才出现。

The solution take a great use of keeping the repositories small and just get one level of data and as I worked with some of the biggest performance issues, the most common issue is often resolved by adding specific function to the repository that loads the nested entities and use some dynamic queries. 该解决方案充分利用了使存储库较小并仅获取一个数据级别的优点,并且当我处理一些最大的性能问题时,最常见的问题通常是通过向存储库添加特定功能来解决,以加载嵌套实体和使用一些动态查询。

ie GetCustomerWithOrderData that includes orders, order rows etc. 即GetCustomerWithOrderData,其中包括订单,订单行等。

Sometimes I have to merge two queries by first get Customer (with included relations) and then get Orders (with included) and map them together by linq. 有时我必须先合并两个查询,首先获取Customer(包含关系),然后获取Orders(包含关系),并通过linq将它们映射在一起。

The queries is far more complex then the examples and the lazy loading could be in business layer, controllers or views so there is wuite alot to trace to resolve. 查询要比示例复杂得多,并且延迟加载可能在业务层,控制器或视图中,因此有很多需要跟踪解决的问题。

But I feel that the code is quite large and I have a hard time finding the future problems. 但是我觉得代码很大,很难找到未来的问题。 What I now need is a good way to track when there is lazy loading, and also be able to tell what objects that need to be loaded on a specific call. 我现在需要的是一种跟踪何时有延迟加载的好方法,并且还能够告诉您在特定调用中需要加载哪些对象。

The best would be if I could track a specific action call, and get what sql that executes, how many times, loadtime etc. 最好的办法是,如果我可以跟踪特定的操作调用,并获取执行的SQL,执行多少次,加载时间等。

The solution is build with MVC 3 and EF4, is there any performance to gain by upgrading to newer EF? 该解决方案是使用MVC 3和EF4构建的,通过升级到较新的EF是否可以获得任何性能?

At a previous job this became an issue as developers would abuse the framework and create n+1 issues all over the place -- only manifesting themselves as the tables grew large. 在上一份工作中,这成为一个问题,因为开发人员会滥用该框架并在整个地方创建n+1问题-仅在表变大时才表现出来。 Plus the lazy loading would create problems with json serialization as well if you didn't specify the serialization depth to stop at 1 -- even at that it was strange that sometimes related objects would be there, at other times they wouldn't (depending on depth). 另外,如果您未指定序列化深度停止为1,那么延迟加载也会对json序列化造成问题,即使这很奇怪,有时相关对象也会在那里,而其他时候却不会(取决于深度)。

In the end, we turned off lazy loading entirely and forced the developers to make the second database call to get the children entities they desired. 最后,我们完全关闭了延迟加载,并迫使开发人员进行第二次数据库调用以获取所需的子实体。 Plus, the team was instructed to leave Sql Server Profiler on while developing to ensure nothing that would kill performance was being created. 此外,还指示该团队在开发时不要打开Sql Server Profiler ,以确保不会破坏性能。

There were definitely cons to this approach as well, such as the extra round trips to the db, the extra lines of code, and the general lack of understanding from new developers to the team why we'd do such a thing. 这种方法也肯定有弊端,例如额外的数据库往返,额外的代码行以及新开发人员到团队普遍缺乏理解的理由。 Some argued that we could use Includes in our queries, but at some point our repositories were becoming bloated by doing so, and simplicity/readability are important too. 有人认为我们可以在查询中使用Includes,但是在某些时候,这样做会使我们的存储库变得肿,简单性/可读性也很重要。 In the end, the performance problems became non-existent, so the trade-off of killing lazy loading was worth it in my opinion. 最后,性能问题不复存在,因此我认为消除延迟加载的权衡是值得的。

This isn't a direct answer to the question, you asked, but maybe it'll give you some additional insight. 您问,这不是问题的直接答案,但也许会给您一些更多的见解。 In your situation, I'd watch Profiler to see where the worst abuse is taking place and then fix it one at a time until your performance is once again acceptable. 在您的情况下,我会看着Profiler查看发生最严重滥用的位置,然后一次对其进行修复,直到您的性能再次被接受。 You'll probably find that your fix is to do something similar, and eliminate lazy loading entirely. 您可能会发现您的解决方法是做类似的事情,并完全消除延迟加载。

I'd love to see other answers to this problem because this is an important topic, in my opinion. 我希望看到该问题的其他答案,因为我认为这是一个重要的话题。

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

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