Skip to content

Commit

Permalink
Clarify some statements in the owned entity types docs
Browse files Browse the repository at this point in the history
Fixes #1239
Fixes #1400
Fixes #1457
Fixes #1628
Fixes #1629
Fixes #1781
Fixes #1888
  • Loading branch information
AndriySvyryd committed Nov 11, 2019
1 parent 6f63ee5 commit cde1961
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 14 deletions.
19 changes: 13 additions & 6 deletions entity-framework/core/modeling/owned-entities.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
---
title: Owned Entity Types - EF Core
description: How to configure owned entity types or aggregates when using Entity Framework Core
author: AndriySvyryd
ms.author: ansvyryd
ms.date: 02/26/2018
ms.assetid: 2B0BADCE-E23E-4B28-B8EE-537883E16DF3
ms.date: 11/06/2019
uid: core/modeling/owned-entities
---
# Owned Entity Types
Expand All @@ -13,7 +13,7 @@ uid: core/modeling/owned-entities
EF Core allows you to model entity 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, they are conceptually similar to [aggregates](https://martinfowler.com/bliki/DDD_Aggregate.html).
Owned entities are essentially a part of the owner and cannot exist without it, they are conceptually similar to [aggregates](https://martinfowler.com/bliki/DDD_Aggregate.html). This means that the owned type is by definition on the dependent side of the relationship with the owner.

## Explicit configuration

Expand Down Expand Up @@ -68,7 +68,7 @@ To configure a different PK call `HasKey`:
[!code-csharp[OwnsMany](../../../samples/core/Modeling/OwnedEntities/OwnedEntityContext.cs?name=OwnsMany)]

> [!NOTE]
> Before EF Core 3.0 `WithOwner()` method didn't exist so this call should be removed.
> Before EF Core 3.0 `WithOwner()` method didn't exist so this call should be removed. Also the primary key was not discovered automatically so it always had be specified.
## Mapping owned types with table splitting

Expand All @@ -80,6 +80,9 @@ You can use the `HasColumnName` method to rename those columns:

[!code-csharp[ColumnNames](../../../samples/core/Modeling/OwnedEntities/OwnedEntityContext.cs?name=ColumnNames)]

> [!NOTE]
> Most of the normal entity type configuration methods like [Ignore](/dotnet/api/microsoft.entityframeworkcore.metadata.builders.ownednavigationbuilder.ignore) can be called in the same way.
## Sharing the same .NET type among multiple owned types

An owned entity type can be of the same .NET type as another owned entity type, therefore the .NET type may not be enough to identify an owned type.
Expand All @@ -100,6 +103,8 @@ In this example `OrderDetails` owns `BillingAddress` and `ShippingAddress`, whic

[!code-csharp[OrderStatus](../../../samples/core/Modeling/OwnedEntities/OrderStatus.cs?name=OrderStatus)]

Each navigation to an owned type defines a separate entity type with completely independent configuration.

In addition to nested owned types, an owned type can reference a regular entity, it can be either the owner or a different entity as long as the owned entity is on the dependent side. This capability sets owned entity types apart from complex types in EF6.

[!code-csharp[OrderDetails](../../../samples/core/Modeling/OwnedEntities/OrderDetails.cs?name=OrderDetails)]
Expand All @@ -108,7 +113,7 @@ It is possible to chain the `OwnsOne` method in a fluent call to configure this

[!code-csharp[OwnsOneNested](../../../samples/core/Modeling/OwnedEntities/OwnedEntityContext.cs?name=OwnsOneNested)]

Notice the `WithOwner` call used to configure the navigation property pointing back at the owner.
Notice the `WithOwner` call used to configure the navigation property pointing back at the owner. To configure a navigation to the owner entity type that's not part of the ownership relationship `WithOwner()` should be called without any arguments.

It is possible to achieve the result using `OwnedAttribute` on both `OrderDetails` and `StreetAdress`.

Expand All @@ -118,6 +123,8 @@ Also unlike EF6 complex types, owned types can be stored in a separate table fro

[!code-csharp[OwnsOneTable](../../../samples/core/Modeling/OwnedEntities/OwnedEntityContext.cs?name=OwnsOneTable)]

It is also possible to use the `TableAttribute` to accomplish this, but note that this would fail if there are multiple navigations to the owned type since in that case multiple entity types would be mapped to the same table.

## 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. Based on the model described before, the following query will get `Order`, `OrderDetails` and the two owned `StreetAddresses` from the database:
Expand All @@ -135,7 +142,7 @@ Some of these limitations are fundamental to how owned entity types work, but so

### Current shortcomings

- Inheritance hierarchies that include owned entity types are not supported
- Owned entity types cannot have inheritance hierarchies
- Reference navigations to owned entity types cannot be null unless they are explicitly mapped to a separate table from the owner
- Instances of owned entity types cannot be shared by multiple owners (this is a well-known scenario for value objects that cannot be implemented using owned entity types)

Expand Down
7 changes: 5 additions & 2 deletions samples/core/Modeling/OwnedEntities/OwnedEntities.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.0-preview2.19525.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.0-preview2.19525.5" />
</ItemGroup>

</Project>
6 changes: 0 additions & 6 deletions samples/core/Modeling/OwnedEntities/OwnedEntityContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
});
#endregion

modelBuilder.Entity<DetailedOrder>().OwnsOne(p => p.OrderDetails, od =>
{
od.Property<int>("OrderId").ValueGeneratedNever();
od.WithOwner(d => d.Order).HasForeignKey("OrderId");
});

#region OwnsMany
modelBuilder.Entity<Distributor>().OwnsMany(p => p.ShippingCenters, a =>
{
Expand Down

0 comments on commit cde1961

Please sign in to comment.