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

标签 c# entity-framework-4

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

类结构如下

订单与许多基本子订单类(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/

相关文章:

c# - 改变选择的RTF

c# - ASP.NET C# Entity Framework - 如何正确更新外键?

c# - 显示 Entity Framework 为插入/更新生成的 SQL

c# - 对于 EF linq 查询,First(c=>cond) 是否等同于 Where(c=>cond).First()?

entity-framework-4 - 在多个项目中共享相同的(.edmx 模型)

.net - 使用更新的值在 Entity Framework 上下文中重新加载对象

c# - 使用 dotnet core 1.1 和 xunit 单元测试显示输出?

c# - .Net 控制台应用程序调用一个 Web API,调用另一个 Web API

c# - LambdaExpression CompileToMethod

c# - ASP.Net上的jpegoptim- “error opening temporary file”