在我们的代码库中,开发人员编写的循环在不知不觉中命中了 Entity Framework 对象中的延迟加载导航属性,从而在循环的每次迭代中触发数据库调用,这是我们的代码库中的一个常见错误。我想知道是否可以使用任何 Visual Studio 扩展或巧妙的技巧来使自动生成的 EF 对象中的属性实际上是导航属性更加明显,以便开发人员更容易意识到要谨慎使用。有什么建议吗?
最佳答案
这里有一些想法:
- 我更喜欢将域对象保持在最低限度,所有属性都是列或导航属性。除了解决您描述的问题之外,这还使消费者非常清楚哪些属性可以在 LINQ 查询中使用(这无济于事的一件事是不是导航属性的复杂属性)
- 尽早结束您的工作单元:
// instead of
using (var work = new MyDbContext())
{
var orders = work.Orders.Where(...).ToList();
foreach (var order in orders)
{
// extra queries issued here
Console.WriteLine(order.Customer.Name);
}
}<p></p>
<pre><code>// consider
List<Order> orders;
using (var work = new MyDbContext())
{
orders = work.Orders.Where(...).ToList();
}
foreach (var order in orders)
{
// now this line throws an exception, so the developer
// will go back and add the .Include() statement instead
// of just silently creating slow code
Console.WriteLine(order.Customer.Name);
}
</code></pre>
<p></p>
考虑关闭延迟加载。这可以在上下文级别上完成,或者通过仅将属性设置为非虚拟来在单个属性级别上完成。虽然延迟加载很方便,但它可能是一个性能陷阱,并且对于代码审查者来说非常不方便,因为需要额外检查
考虑使用 DbInterceptor在您的测试环境中查找延迟加载查询(它们非常独特)并记录问题
让人们练习使用 SqlServer Profiler 或 MiniProfiler开发时开启。这使得很容易发现何时发出太多查询。
使用 Roslyn,您可能可以编写 analyzer它静态分析代码并在引用这些属性以调用它们时显示一些诊断信息。
关于c# - 使 Linq 导航属性对开发人员来说更加明显,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34645716/