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

时间:2016-01-07 01:06:11

标签: c# entity-framework linq linq-to-sql linq-to-entities

我们的代码库中常见的错误是开发人员编写了循环,这些循环在不知不觉中命中了Entity Framework对象中的延迟加载导航属性,从而在循环中每次迭代时触发数据库调用。我想知道是否可以使用任何Visual Studio扩展或聪明的技巧使自动生成的EF对象中的属性实际上是导航属性更明显,以便开发人员更容易意识到要谨慎使用。有什么建议吗?

1 个答案:

答案 0 :(得分:2)

以下是一些想法:

  • 我更喜欢保持域对象最小化,所有属性都是列或导航属性。除了解决您描述的问题之外,这使得消费者非常明显可以在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);
        }
    }

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

  • 考虑关闭延迟加载。这可以在上下文级别上完成,也可以在单个属性级别上完成,只需使属性非虚拟。虽然延迟加载很方便,但它可能是一个性能陷阱,并且代码审查员非常不方便作为额外的检查方法

  • 考虑在您的测试环境中使用DbInterceptor查找延迟加载查询(它们非常独特)并记录问题

  • 让人们在开发过程中使用SqlServer Profiler或MiniProfiler。这样可以很容易地发现何时发出太多查询。

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