EFCore-如何从自动加载中排除拥有的对象? [英] EFCore - How to exclude owned objects from automatic loading?

查看:219
本文介绍了EFCore-如何从自动加载中排除拥有的对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在设法把头放在EF Cores拥有的对象上,以及如何控制何时加载某些数据块。



基本上,我有一堆旧的遗留表(有些具有约150列),并希望使用一个根实体和每个表几个拥有的对象对其进行建模,以实现更好的细分并捆绑某些功能。示例:存在一个文章实体,其中包含基础表中最重要字段的约20个属性。该实体还包含一个OwnedObject StorageDetails,该对象包装了更多字段(以及所有与存储内容有关的功能)。



问题:我找不到方法控制是否应立即加载拥有的对象。对于它们中的某些,我希望使用Include()显式加载它们。

 公共类Article:EntityBase 
{
公共字符串ArticleNumber {get; set; }

//拥有的对象,共享商品编号作为密钥。
public StorageDetails StorageStuff {get;组; }

//来自另一个具有外键引用的表的实体
public SomeOtherEntity OtherStuff {get;组; }
}

公共类StorageDetails:OwnedObject< Article>
{
公共物品所有者{得到;组; }
}

//创建模型期间的某个地方...
builder.OwnsOne(article => article.StorageStuff);

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

使用OwnsOne定义模型并立即加载文章,将立即加载StorageStuff。要加载OtherThing,我必须在查询中将它添加到Inlcude()中,这基本上是我要为拥有的对象实现的功能。



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

解决方案

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


$ Build <实体().OwnsOne(e => e.SorageStuff)
.Metadata.PrincipalToDependent?.SetIsEagerLoaded(false);

这允许通过 Include / 然后包括。但是由于EF Core实施的特定性,拥有实体类型不能使用显式/延迟加载。尝试这样做会导致运行时异常。因此,我从原始答案中得到的建议仍然适用。


原文:
具有自有类型-目前尚不可能,因为这种行为是 ;通过设计。并且记录在查询拥有的类型< EF Core文档的/ a>部分:


查询所有者时,默认情况下将包括拥有的类型。即使拥有的类型存储在单独的表中,也不必使用Include方法。


用 by表示有点含糊默认值,但是您可以放心地将其读为始终,因为没有选项或排除方法。




由于当前控制加载相关数据的唯一方法是 real 实体的导航属性,因此将要控制的类型设置为真实实体,即不要标记将它们视为拥有者,定义显式PK或影子PK,并映射这些实体。与表拆分


现在可以将两个或多个实体类型映射到将共享主键列的同一个表中,每个该行将与两个或多个实体相对应。


要使用表拆分,必须在共享表的所有实体类型之间配置标识关系(外键属性构成主键):



I'm trying to wrap my head around EF Cores owned objects and how i can control when to load certain chunks of data.

Basically i'm having a bunch of old legacy tables (some with ~150 columns) and want to model them using a root entity and several owned objects per table to achieve better segmentation and bundle certain functionalities. Example: There is an "article" entity containing ~20 properties for the most important fields of the underlying table. That entity also contains an OwnedObject "StorageDetails" wrapping a dozen more fields (and all the functions concerned with storing stuff).

Problem: I can't find a way to control if an owned object should be loaded immediatly or not. For some of them i would prefer to load them explicitly using 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 ) 
       ...

Defining the model with OwnsOne and loading an article immediatly loads the StorageStuff. To load the OtherThing i have to Inlcude() it in a query, which is basically what i want to achieve for the owned object.

Is that possible? If not, what other approach could you point me to?

解决方案

Update: I wasn't exact right - the implicit eager loading of owned entity types is really a default and can be changed via SetIsEagerLoaded metadata API (EF Core 3.0+)

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

This allows loading them via Include / ThenInclude. But due to EF Core implementation specifics, owned entity types cannot use explicit/lazy loading. Trying to do so leads to runtime exception. So my recommendation from the original answer still applies.

Original: With owned types - it's not possible (currently), because this behavior is "by design". And is documented in Querying owned types section of the EF Core documentation:

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.

It's a bit vague by saying "by default", but you can safely read it as "always", because there is no option or Exclude method.


Since currently the only way to control loading related data is navigation property to a real entity, make the types you want to control a "real entities", i.e. don't mark them as owned, define explicit or shadow PK, and map these "entities" with 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:

这篇关于EFCore-如何从自动加载中排除拥有的对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆