Skip to content

Commit

Permalink
Add documentation for mapping two properties to the same column when …
Browse files Browse the repository at this point in the history
…using TPH

Fixes #529
  • Loading branch information
AndriySvyryd committed Nov 7, 2019
1 parent 00f8660 commit 9b8ec19
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 56 deletions.
7 changes: 4 additions & 3 deletions entity-framework/core/modeling/inheritance.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
---
title: Inheritance - EF Core
author: rowanmiller
description: How to configure entity type inheritance using Entity Framework Core
author: AndriySvyryd
ms.author: ansvyryd
ms.date: 10/27/2016
ms.assetid: 754be334-dd21-450e-9d22-2591e80012a2
uid: core/modeling/inheritance
---
# Inheritance
Expand All @@ -11,7 +12,7 @@ Inheritance in the EF model is used to control how inheritance in the entity cla

## Conventions

By convention, it is up to the database provider to determine how inheritance will be represented in the database. See [Inheritance (Relational Database)](relational/inheritance.md) for how this is handled with a relational database provider.
By default, it is up to the database provider to determine how inheritance will be represented in the database. See [Inheritance (Relational Database)](relational/inheritance.md) for how this is handled with a relational database provider.

EF will only setup inheritance if two or more inherited types are explicitly included in the model. EF will not scan for base or derived types that were not otherwise included in the model. You can include types in the model by exposing a *DbSet\<TEntity>* for each type in the inheritance hierarchy.

Expand Down
4 changes: 2 additions & 2 deletions entity-framework/core/modeling/keyless-entity-types.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
---
title: Keyless Entity Types - EF Core
description: How to configure keyless entity types using Entity Framework Core
author: AndriySvyryd
ms.author: ansvyryd
ms.date: 02/26/2018
ms.assetid: 9F4450C5-1A3F-4BB6-AC19-9FAC64292AAD
ms.date: 9/13/2019
uid: core/modeling/keyless-entity-types
---
# Keyless Entity Types
Expand Down
65 changes: 16 additions & 49 deletions entity-framework/core/modeling/relational/inheritance.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
---
title: Inheritance (Relational Database) - EF Core
author: rowanmiller
ms.date: 10/27/2016
ms.assetid: 9a7c5488-aaf4-4b40-b1ff-f435ff30f6ec
description: How to configure entity type inheritance in a relational database using Entity Framework Core
author: AndriySvyryd
ms.author: ansvyryd
ms.date: 11/06/2019
uid: core/modeling/relational/inheritance
---
# Inheritance (Relational Database)
Expand All @@ -17,7 +18,7 @@ Inheritance in the EF model is used to control how inheritance in the entity cla
## Conventions

By convention, inheritance will be mapped using the table-per-hierarchy (TPH) pattern. TPH uses a single table to store the data for all types in the hierarchy. A discriminator column is used to identify which type each row represents.
By default, inheritance will be mapped using the table-per-hierarchy (TPH) pattern. TPH uses a single table to store the data for all types in the hierarchy. A discriminator column is used to identify which type each row represents.

EF Core will only setup inheritance if two or more inherited types are explicitly included in the model (see [Inheritance](../inheritance.md) for more details).

Expand All @@ -44,48 +45,14 @@ You can use the Fluent API to configure the name and type of the discriminator c

In the examples above, the discriminator is created as a [shadow property](xref:core/modeling/shadow-properties) on the base entity of the hierarchy. Since it is a property in the model, it can be configured just like other properties. For example, to set the max length when the default, by-convention discriminator is being used:

```C#
modelBuilder.Entity<Blog>()
.Property("Discriminator")
.HasMaxLength(200);
```

The discriminator can also be mapped to an actual CLR property in your entity. For example:

```C#
class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.HasDiscriminator<string>("BlogType");
}
}

public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public string BlogType { get; set; }
}

public class RssBlog : Blog
{
public string RssUrl { get; set; }
}
```

Combining these two things together it is possible to both map the discriminator to a real property and configure it:

```C#
modelBuilder.Entity<Blog>(b =>
{
b.HasDiscriminator<string>("BlogType");

b.Property(e => e.BlogType)
.HasMaxLength(200)
.HasColumnName("blog_type");
});
```
[!code-csharp[Main](../../../../samples/core/Modeling/FluentAPI/DefaultDiscriminator.cs#DiscriminatorConfiguration)]

The discriminator can also be mapped to a .NET property in your entity and configure it. For example:

[!code-csharp[Main](../../../../samples/core/Modeling/FluentAPI/NonShadowDiscriminator.cs#NonShadowDiscriminator)]

## Shared columns

When two sibling entity types have a property with the same name they will be mapped to two separate columns by default. But if they are compatible they can be mapped to the same column:

[!code-csharp[Main](../../../../samples/core/Modeling/FluentAPI/SharedTPHColumns.cs#SharedTPHColumns)]
2 changes: 1 addition & 1 deletion entity-framework/core/modeling/table-splitting.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
---
title: Table Splitting - EF Core
description: How to configure table splitting using Entity Framework Core
author: AndriySvyryd
ms.author: ansvyryd
ms.date: 04/10/2019
ms.assetid: 0EC2CCE1-BD55-45D8-9EA9-20634987F094
uid: core/modeling/table-splitting
---
# Table Splitting
Expand Down
29 changes: 29 additions & 0 deletions samples/core/Modeling/FluentAPI/DefaultDiscriminator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore;

namespace EFModeling.FluentAPI.DefaultDiscriminator
{
public class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
#region DiscriminatorConfiguration
modelBuilder.Entity<Blog>()
.Property("Discriminator")
.HasMaxLength(200);
#endregion
}
}

public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}

public class RssBlog : Blog
{
public string RssUrl { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace EFModeling.FluentAPI.InheritanceTphDiscriminator
{
#region Inheritance
class MyContext : DbContext
public class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }

Expand Down
38 changes: 38 additions & 0 deletions samples/core/Modeling/FluentAPI/NonShadowDiscriminator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using Microsoft.EntityFrameworkCore;

namespace EFModeling.FluentAPI.NonShadowDiscriminator
{
#region NonShadowDiscriminator
public class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property("Discriminator")
.HasMaxLength(200);

modelBuilder.Entity<Blog>()
.HasDiscriminator(b => b.BlogType);

modelBuilder.Entity<Blog>()
.Property(e => e.BlogType)
.HasMaxLength(200)
.HasColumnName("blog_type");
}
}

public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public string BlogType { get; set; }
}

public class RssBlog : Blog
{
public string RssUrl { get; set; }
}
#endregion
}
37 changes: 37 additions & 0 deletions samples/core/Modeling/FluentAPI/SharedTPHColumns.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using Microsoft.EntityFrameworkCore;

namespace EFModeling.FluentAPI.SharedTPHColumns
{
#region SharedTPHColumns
public class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property(b => b.Url)
.HasColumnName("Url");

modelBuilder.Entity<RssBlog>()
.Property(b => b.Url)
.HasColumnName("Url");
}
}

public class BlogBase
{
public int BlogId { get; set; }
}

public class Blog : BlogBase
{
public string Url { get; set; }
}

public class RssBlog : BlogBase
{
public string Url { get; set; }
}
#endregion
}

0 comments on commit 9b8ec19

Please sign in to comment.