serge
serge

Reputation: 15219

On the "owned" types in EF Core

In my project, I use the EF Core fluent config, code first. I read a little about the owned types, but the situation bellow is not really clear to me:

Suppose I have a Project entity and a ProjectType.
Should I map that property as :

Entity<Project>.HasOne<ProjectType>(); or rather as
Entity<Project>.OwnsOne<ProjectType>();

The ProjectType entity should be mapped to a table ProjectType(ProjectTypeId, Name, Description)

As I read, owned are

"types that can only ever appear on navigation properties of other entity types. These are called owned entity types. The entity containing an owned entity type is its owner. Owned entities are essentially a part of the owner and cannot exist without it"

In my case

"ProjectType can only ever appear on navigation properties of Project entity type. ProjectType is essentially a part of the Project and cannot exist without it"... however, in order to create a separate table, as I understood I need to use HasOne, not OwnsOne... would be great if someone explain better this idea. Thanks a lot.

Upvotes: 2

Views: 3169

Answers (1)

Steve Py
Steve Py

Reputation: 34653

ProjectTypes sound like a reference table that might otherwise be modifiable over the course of an application's lifespan, such as through a system administration role. Usage of the new "Owns" is a convention to help enforce concepts like type-specific composition, and linking tables in a relational data model.

A better example for composition: Say you have a Project and as a part of a Project there are some details that are fairly large, and infrequently used. Things like an image or other binary data, or perhaps some large text. Having these BLOB/CLOB details inside the Project table can be a recipe for disaster when you fetch a Project, or many Projects, so you normalize them out into a separate related table called ProjectDetails, or possibly several related tables. This way, for the most part when you are working with Project and loading those entities you don't have to worry about pulling back these large fields all of the time, you can reference a ProjectDetails to include only when it is actually needed. Since ProjectDetails doesn't really serve any purpose on it's own, it doesn't need a DbSet or anything of the like, so we can set up the relationship from Project to OwnsOne ProjectDetails.

ProjectType on the other hand would potentially have a DbSet to establish new project types over the course of configuring an application. You may also want to associate other project-related details based on a Project Type. In this case it would make more sense for Project to HasOne ProjectType. We can have a DbSet of ProjectTypes to manage, and other entities may filter by ProjectTYpe as well, Project Stages/Phases, etc.

As far as the database schema goes between Owns and Has, there is no difference. It's solely about how the EF DbContext will expect to work with the entities.

Other common examples of using Owns are linking tables. For instance you have an Address table which is shared between Orders, Customers, etc. Neither "Owns" addresses, but they do own their linking table: Order Owns OrderAddress, Customer Owns CustomerAddress. These entities "Has" an Address. We may still want to review Addresses as they represent physical locations and there is a difference between associating an Order etc. to a different location, and "adjusting" the details recorded for a physical location. (I.e. correcting a street name or municipality) There is not a need to ever deal with OrderAddresses or CustomerAddresses outside of the scope of the Order or Customer respectively.

Upvotes: 4

Related Questions