实体框架 - 子类相关的对象预先加载 [英] Entity Framework - Eager loading of subclass related objects

查看:145
本文介绍了实体框架 - 子类相关的对象预先加载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道是否有可能为定类的子类,某些急于负载相关的实体。

I wonder if there is a possibility to eager load related entities for certain subclass of given class.

类结构如下

订单有关系的许多基亚类(SuborderBase)。 MySubOrder类从SuborderBase继承。我要为包括()来加载顺序加载时,相关MySubOrder实体(客户)到指定路径,但我得到了一个错误,声称有SuborderBase和客户之间没有任何关系。但关系MySubOrder和客户之间存在。

Order has relation to many base suborder classes (SuborderBase). MySubOrder class inherits from SuborderBase. I want to specify path for Include() to load MySubOrder related entities (Customer) when loading Order, but I got an error claiming that there is no relation between SuborderBase and Customer. But relation exists between MySubOrder and Customer.

下面是查询失败

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

我怎么可以指定明确的?

How can I specify that explicitly?

更新。实体方案低于

Update. Entity scheme is below

推荐答案

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

This is a solution which requires only a single roundtrip:

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

它基本上是一个投影到一个匿名类型的集合。事后查询结果被变换成在存储器中的实体和导航属性。 (它还可以与禁用跟踪。)

It is basically a projection into an anonymous type collection. Afterwards the query result is transformed into entities and navigation properties in memory. (It also works with disabled tracking.)

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

If you don't need entities you can omit the whole part after the first ToList() and work directly with the result in the anonymous objects.

如果您必须修改此对象图而需要变更跟踪,我不知道这种做法是安全的,因为数据被加载时的导航属性未完全设置 - 例如 MyOrder.Customers 投影后,然后设置在内存中关系属性可以作为一种修正,它是检测不出来制造麻烦,当你调用的SaveChanges

If you must modify this object graph and need change tracking, I am not sure if this approach is safe because the navigation properties are not completely set when the data are loaded - for example MyOrder.Customers is null after the projection and then setting relationship properties in memory could be detected as a modification which it isn't and cause trouble when you call SaveChanges.

预测是为只读场景制作,没有进行修改。如果您需要更改跟踪可能更安全的方法是加载多次往返完整的实体,因为没有办法使用包含在一个单一的往返加载整个对象图你的的局面。

Projections are made for readonly scenarios, not for modifications. If you need change tracking the probably safer way is to load full entities in multiple roundtrips as there is no way to use Include in a single roundtrip to load the whole object graph in your situation.

这篇关于实体框架 - 子类相关的对象预先加载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆