Skip to content

Commit

Permalink
Add documentation for complete discriminator mapping (#2853)
Browse files Browse the repository at this point in the history
Resolves #2231
  • Loading branch information
smitpatel authored Nov 10, 2020
1 parent 6f73ae5 commit 9cf4d52
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
6 changes: 5 additions & 1 deletion entity-framework/core/modeling/inheritance.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ If you don't want to expose a `DbSet` for one or more entities in the hierarchy,

By default, EF maps the inheritance using the *table-per-hierarchy* (TPH) pattern. TPH uses a single table to store the data for all types in the hierarchy, and a discriminator column is used to identify which type each row represents.

The model above is mapped to the following database schema (note the implicitly-created `Discriminator` column, which identifies which type of `Blog` is stored in each row).
The model above is mapped to the following database schema (note the implicitly created `Discriminator` column, which identifies which type of `Blog` is stored in each row).

![Screenshot of the results of querying the Blog entity hierarchy using table-per-hierarchy pattern](_static/inheritance-tph-data.png)

Expand All @@ -45,6 +45,10 @@ Finally, the discriminator can also be mapped to a regular .NET property in your

[!code-csharp[Main](../../../samples/core/Modeling/FluentAPI/NonShadowDiscriminator.cs?name=NonShadowDiscriminator&highlight=4)]

When querying for derived entities, which use the TPH pattern, EF Core adds a predicate over discriminator column in the query. This filter makes sure that we don't get any additional rows for base types or sibling types not in the result. This filter predicate is skipped for the base entity type since querying for the base entity will get results for all the entities in the hierarchy. When materializing results from a query, if we come across a discriminator value, which isn't mapped to any entity type in the model, we throw an exception since we don't know how to materialize the results. This error only occurs if your database contains rows with discriminator values, which aren't mapped in the EF model. If you have such data, then you can mark the discriminator mapping in EF Core model as incomplete to indicate that we should always add filter predicate for querying any type in the hierarchy. `IsComplete(false)` call on the discriminator configuration marks the mapping to be incomplete.

[!code-csharp[Main](../../../samples/core/Modeling/FluentAPI/DiscriminatorMappingIncomplete.cs?name=DiscriminatorMappingIncomplete&highlight=5)]

### Shared columns

By default, when two sibling entity types in the hierarchy have a property with the same name, they will be mapped to two separate columns. However, if their type is identical they can be mapped to the same database column:
Expand Down
29 changes: 29 additions & 0 deletions samples/core/Modeling/FluentAPI/DiscriminatorMappingIncomplete.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore;

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

#region DiscriminatorMappingIncomplete
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.HasDiscriminator()
.IsComplete(false);
}
#endregion
}

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

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

0 comments on commit 9cf4d52

Please sign in to comment.