【问题标题】:Eager Loading Complex Query with Entity Framework 5使用 Entity Framework 5 急切加载复杂查询
【发布时间】:2013-06-18 03:01:35
【问题描述】:

我正在为计划日历加载 ServiceTrips,想知道是否有最快的方法可以从许多表中急切加载相关数据。

这是需要加载的模型(映射是每个具体类型的表)

public class ServiceTrip : BaseEntity
{
    public ICollection<Employee> Crew { get; set; }
    public ICollection<ServiceAssignment> Assignments { get; set; }
}

public class ServiceAssignment : BaseEntity
{
    public ServiceOrder ServiceOrder { get; set; }
    public DeliveryOrder DeliveryOrder { get; set; }
}

public class ServiceOrder : OrderBase { }
public class DeliveryOrder : OrderBase { }

public abstract class OrderBase : BaseEntity
{
    public ICollection<ServiceAssignment> Assignments { get; set; }
    public Sale Sale { get; set; }
}

public class Sale : BaseEntity
{
    public Employee Manager { get; set; }
    public Customer Customer { get; set; }
    public ICollection<ServiceOrder> ServiceOrders { get; set; }
    public ICollection<DeliveryOrder> DeliveryOrders { get; set; }
}

public class Employee : BaseEntity { }
public class Customer : BaseEntity { }

public abstract class BaseEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
}

我基本上已经尝试过这样的事情,但不知道从哪里开始。

var tripsQuery = db.ServiceTrips

.Where(x => x.StartDate >= FirstDay && x.StartDate <= LastDay)

.Include(x => x.Crew)
.Include(x => x.ServiceAssignments)

.Include(x => x.ServiceAssignments.Select(y => y.DeliveryOrder))
.Include(x => x.ServiceAssignments.Select(y => y.ServiceOrder))

.Include(x => x.ServiceAssignments.Select(y => y.DeliveryOrder.Sale))
.Include(x => x.ServiceAssignments.Select(y => y.ServiceOrder.Sale))

.Include(x => x.ServiceAssignments.Select(y => y.DeliveryOrder.Sale.Customer))
.Include(x => x.ServiceAssignments.Select(y => y.ServiceOrder.Sale.Customer))

.Include(x => x.ServiceAssignments.Select(y => y.DeliveryOrder.Sale.Manager))
.Include(x => x.ServiceAssignments.Select(y => y.ServiceOrder.Sale.Manager))
;

针对问题简化了模型。在生产中,我从大约 20 张桌子中抽出。加载大约需要 10-15 秒。我尝试每天异步加载,但这增加了加载的总时间。

【问题讨论】:

  • 性能取决于很多因素,结果集的大小,如果您正在扫描的列上有索引等。我的建议是在原始 SQL 中重现您尝试执行的操作,这将使您了解您的查询当前是否不合理。
  • 因为没有一个集合是 virtual,我会断言数据是在没有任何 Include 的情况下急切加载的
  • @qujck 是的,没错。这是我在简化问题模型时犯的一个错误。它们在我的生产模型中是虚拟的,但我明确禁用延迟加载。

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


【解决方案1】:

在我看来,当您发出一个连接 20 个表的复杂查询时,您可能希望从检查数据库本身开始

这里有一些指导原则(有些点与 SQL Server 相关,我冒昧地假设是您正在使用的数据库)

  1. 检查原始 SQL 上的查询执行计划 - 如果在 SQL 中重现整个 EF 代码很耗时,可能只是其中的一部分 - 例如 ServiceTrips、ServiceAssignments 和 DeliveryOrder 表。这将使您了解索引等方面的瓶颈

  2. 检查是否由于数据的大小,网络延迟是瓶颈,而不是查询本身

  3. 考虑使用indexed views,这可能会提高您的性能

  4. 架构 - 为了加快此类复杂查询的速度,请使用某种缓存来存储相关数据 - 在您的情况下,可能是经理、船员的姓名等等。

【讨论】:

  • 谢谢。结果证明是几件事的结合。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多