所以我的 DbContext 上有以下模型类:
每次我呈现一个 LoanApplication 对象列表时,我都会做这样的事情:
var context = new MyContext();
var applications = context.LoanApplications.Where(d => d.PropertyThatIWantToFilter = localVariable);
这会返回一个 IQueryable,然后我在我的 Controller 方法调用中将其转换为这样的 ViewModel:
var vm = applications.Select(d => new LoanApplicationViewModel(d));
在 LoanApplicationViewModel
构造函数中,我接受实体对象并进行相应的映射。事情是这样的,因为 Solicitors 集合是一个导航属性,每次实例化一个新的 View 模型时都会调用数据库。每个应用程序的平均律师数量是两个,这意味着如果我呈现一个列出最后 10 个应用程序的表,那么该应用程序将对数据库进行大约 18-20 次访问。
我认为必须有更好的方法来获取这个集合,所以我改变了我原来的查询来像这样急切地加载这个集合:
var applications = context.LoanApplications.Include("Solicitors").Where...
虽然这将对数据库的调用次数减少到只有一次,但查询速度要慢得多,大约慢了 50%。
数据库托管在 SQL Azure 上,我们已经实现了 transient 故障处理,但我想在不降低响应时间性能的情况下减少对数据库的调用数量。
此处的最佳做法是什么?
最佳答案
“这里的最佳实践是什么?”
最好的做法是
- 设置应用范围!绩效目标
- 剖析、基准测试并定位瓶颈
- 检查并微调瓶颈,让您以最少的工作获得最大的性能。 (根据我的经验,90% 的时间都不是 tsql)
现在这似乎有点无关紧要,但从那个角度来看,您在应用程序域中配置的最佳加载模式是正确的方法。
没有急切/懒惰的“最佳实践”。这就是为什么这两个选项都可用的原因。此外,如果 tsql 是您的瓶颈并且在 eager/lazy 之间切换仍然没有达到您的性能目标,您将需要使用大量其他工具,例如 SSMS 中的查询分析器和查询计划分析器。
一些背景:
我在谷歌上搜索“eager loading slow”然后来到这里。这是我的结果:
var foo = _context.Foos
//.Include("Answers")
//.Include("Attachments")
.FirstOrDefault(q => q.Id == key);
预加载:106 毫秒
延迟加载:11ms + 5ms + 5ms
延迟加载获胜,故事结束。
关于c# - Entity Framework 上的延迟加载与急切加载性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15778375/