EFCore - How to exclude owned objects from automatic loading?

c# data-modeling entity-framework-core owned-types


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?

1/4/2019 3:26:07 PM

Accepted Answer

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:

1/11/2019 7:40:08 AM

Related Questions


Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow