实体框架 - 渴望加载子类相关对象

时间:2011-10-03 12:46:01

标签: c# entity-framework-4

我想知道是否有可能为给定类的某个子类加载相关实体。

类结构在

之下

Order与许多基本子类(SuborderBase)有关。 MySubOrder类继承自SuborderBase。我想在加载Order时指定Include()加载MySubOrder相关实体(Customer)的路径,但是我得到一个错误,声称SuborderBase和Customer之间没有关系。但是MySubOrder和Customer之间存在关系。

以下是查询失败

Context.Orders.Include("SubOrderBases").Include("SubOrderBases.Customers")

如何明确指定?

更新。实体计划如下 enter image description here

2 个答案:

答案 0 :(得分:13)

这是一个只需要一次往返的解决方案:

var orders = Context.Orders
    .Select(o => new
    {
        Order = o,
        SubOrderBases = o.SubOrderBases.Where(s => !(s is MyOrder)),
        MyOrdersWithCustomers = o.SubOrderBases.OfType<MyOrder>()
            .Select(m => new
            {
                MyOrder = m,
                Customers = m.Customers
            })
    })
    .ToList()  // <- query is executed here, the rest happens in memory
    .Select(a => 
    {
        a.Order.SubOrderBases = new List<SubOrderBase>(
            a.SubOrderBases.Concat(
            a.MyOrdersWithCustomers.Select(m => 
                {
                    m.MyOrder.Customers = m.Customers;
                    return m.MyOrder;
                })));
        return a.Order;
    })
    .ToList();

它基本上是对匿名类型集合的投影。然后将查询结果转换为内存中的实体和导航属性。 (它也适用于禁用跟踪。)

如果您不需要实体,可以在第一个ToList()之后省略整个部分,并直接使用匿名对象中的结果。

如果您必须修改此对象图并需要更改跟踪,我不确定此方法是否安全,因为加载数据时导航属性未完全设置 - 例如MyOrder.Customers为{{1}在投影之后,然后在内存中设置关系属性可以被检测为不是的修改,并且在您调用null时会造成麻烦。

针对只读方案进行预测,而不是进行修改。如果您需要更改跟踪,可能更安全的方法是在多个往返中加载完整实体,因为在您的情况下无法在单个往返中使用SaveChanges来加载整个对象图。

答案 1 :(得分:0)

假设您将订单列表加载为lstOrders,请尝试:

foreach (Orders order in lstOrders)
    order.SubOrderBases.Load();

和客户一样..