gpt4 book ai didi

c# - Entity Framework - 子类相关对象的预加载

转载 作者:可可西里 更新时间:2023-11-01 09:05:36 25 4
gpt4 key购买 nike

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

类结构如下

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

下面是失败的查询

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

如何明确指定?

更新。实体方案如下 enter image description here

最佳答案

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

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在投影之后为 null,然后在内存中设置关系属性可能会被检测为修改,但它不是,并在您调用 SaveChanges 时造成麻烦。

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

关于c# - Entity Framework - 子类相关对象的预加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7635152/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com