EFCore - 如何从自动加载中排除拥有的对象?

EFCore - How to exclude owned objects from automatic loading?

我正在努力思考 EF Cores 拥有的对象以及如何控制何时加载某些数据块。

基本上我有一堆旧遗留 table(有些有 ~150 列)并且想使用根实体和每个 table 的几个拥有对象来建模它们以获得更好的效果细分和捆绑某些功能。示例:有一个 "article" 实体包含基础 table 最重要字段的 ~20 个属性。该实体还包含一个 OwnedObject "StorageDetails" 包装了十几个字段(以及所有与存储内容有关的函数)。

问题:我找不到一种方法来控制是否应立即加载拥有的对象。对于其中一些,我更愿意使用 Include() 显式加载它们 ...

public class Article : EntityBase
{  
    public string ArticleNumber { get;set; }

    // Owned object, shares article number as key.
    public StorageDetails StorageStuff { get; set; }

    // An Entity from another table having a foreign key reference 
    public SomeOtherEntity OtherStuff { get; set; }
}

public class StorageDetails : OwnedObject<Article>
{
    public Article Owner { get; set; }
}

// Somewhere during model creation ...
builder.OwnsOne(article => article.StorageStuff);

builder.HasOne(article => article.OtherStuff ) 
       ...

使用 OwnsOne 定义模型并加载文章会立即加载 StorageStuff。要加载 OtherThing,我必须在查询中对其进行 Inlcude(),这基本上是我想要为拥有的对象实现的。

这可能吗?如果没有,您还能指出什么其他方法?

更新: 我不完全正确 - 拥有的实体类型的隐式预加载实际上是一个 默认值 并且可以更改通过 SetIsEagerLoaded 元数据 API (EF Core 3.0+)

modelBuilder.Entity<Article>().OwnsOne(e => e.StorageStuff)
    .Metadata.PrincipalToDependent?.SetIsEagerLoaded(false);

AutoInclude流利API(EF Core 5.0+)

modelBuilder.Entity<Article>().Navigation(e => e.StorageStuff)
    .AutoInclude(false);

这允许通过 Include / ThenInclude 预先加载它们。但由于 EF Core 实现细节,拥有的实体类型不能使用 explicit/lazy 加载。尝试这样做会导致运行时异常。所以我从原来的答案中得到的建议仍然适用。

原文: 对于拥有的类型——这是不可能的(目前),因为这种行为是“设计使然”的。并记录在 EF Core 文档的 Querying owned types 部分:

When querying the owner the owned types will be included by default. It is not necessary to use the Include method, even if the owned types are stored in a separate table.

说“默认”有点含糊,但您可以放心地将其理解为“始终”,因为没有选项或 Exclude 方法。


由于目前控制加载相关数据的唯一方法是导航属性到真实实体,将您想要控制的类型设为“真实实体”,即不要将它们标记为拥有,定义显式或影子 PK,并将这些“实体”映射为 Table Splitting:

It is now possible to map two or more entity types to the same table where the primary key column(s) will be shared and each row will correspond to two or more entities.

To use table splitting an identifying relationship (where foreign key properties form the primary key) must be configured between all of the entity types sharing the table: