实体框架 - 子类相关的对象预先加载 [英] Entity Framework - Eager loading of subclass related objects
问题描述
我不知道是否有可能为定类的子类,某些急于负载相关的实体。
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屋!