Reputation: 15219
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
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