我不知道是否有可能为给定类的某些子类加载相关实体.
课堂结构如下
订单与许多基础子类(SuborderBase)有关. MySubOrder类继承自SuborderBase.我想在加载Order时指定Include()加载MySubOrder相关实体(Customer)的路径,但是我收到一条错误,声称SuborderBase和Customer之间没有关系.但MySubOrder与Customer之间存在关系.
以下是查询失败
Context.Orders.Include("SubOrderBases").Include("SubOrderBases.Customers")
如何明确指定?
更新.实体方案如下
解决方法
这是一个仅需要单程往返的解决方案:
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为空,然后设置关系属性在内存中可以被检测为一个修改,它不是并且在调用SaveChanges时引起麻烦.
预测是针对只读方案进行的,而不是进行修改.如果您需要更改跟踪,则可能更安全的方式是在多个往返中加载完整实体,因为在您的情况下无法使用单个往返中的Include加载整个对象图.