我想知道是否有可能为给定类的某个子类加载相关实体。
类结构在
之下Order与许多基本子类(SuborderBase)有关。 MySubOrder类继承自SuborderBase。我想在加载Order时指定Include()加载MySubOrder相关实体(Customer)的路径,但是我得到一个错误,声称SuborderBase和Customer之间没有关系。但是MySubOrder和Customer之间存在关系。
以下是查询失败
Context.Orders.Include("SubOrderBases").Include("SubOrderBases.Customers")
如何明确指定?
更新。实体计划如下
答案 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();
和客户一样..