使 Linq 导航属性对开发人员更加明显

Making Linq navigation properties more obvious to developers

我们代码库中的一个常见错误是开发人员编写的循环不知不觉地命中了 Entity Framework 对象中的惰性加载导航属性,从而在循环中的每次迭代中触发了 DB 调用。我想知道是否可以使用任何 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>

<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);
}

  • 考虑关闭延迟加载。这可以在上下文级别上完成,也可以在个人 属性 级别上通过仅创建属性 non-virtual 来完成。虽然 lazy-loading 很方便,但它可能是一个性能陷阱,并且对于代码审查人员来说非常不方便,因为需要额外检查

  • 考虑在您的测试环境中使用 DbInterceptor 来查找 lazy-load 查询(它们非常独特)并记录问题

  • 让人们在开发时练习使用 SqlServer Profiler 或 MiniProfiler。这使得在发出过多查询时很容易发现。

  • 使用 Roslyn,您可能会编写一个 analyzer,它静态分析代码并在引用这些属性以调用它们时显示一些诊断信息。