Quantcast
Channel: Development With A Dot
Viewing all articles
Browse latest Browse all 404

Entity Framework Code First Inheritance

$
0
0

Introduction

Another post for self reference, this time, how to map inheritance strategies with Entity Framework Code First.

Single Table Inheritance / Table Per Class Hierarchy

First, the default strategy: one table for all classes in the hierarchy. Will store all columns on the same table, so all properties on derived classes must be nullable, and there will be lots of nulls. An additional column will be created, which will contain a discriminator value for deciding which type corresponds to each row.

   1: [Table("Base")]
   2:publicabstractclass Base
   3: {
   4:public Int32 BaseId { get; set; }
   5:  
   6:public String InheritedColumn { get; set; }
   7: }

 

   1:publicclass DerivedA : Base
   2: {
   3:public String A { get; set; }
   4: }

 

   1:publicclass DerivedB : Base
   2: {
   3:public String B { get; set; }
   4: }

 

image

 

Class Table Inheritance / Table Per Type

This will map all properties of the base class into a table of its own and each derived class in its own table, connected to the base table by a foreign key. No duplication will occur and properties on derived classes can be mapped as not nullable.

   1: [Table("Base")]
   2:publicabstractclass Base
   3: {
   4:public Int32 BaseId { get; set; }
   5:  
   6:public String InheritedColumn { get; set; }
   7: }

 

   1: [Table("DerivedA")]
   2:publicclass DerivedA : Base
   3: {
   4:public String ColumnA { get; set; }
   5: }

 

   1: [Table("DerivedB")]
   2:publicclass DerivedB : Base
   3: {
   4:public String ColumnB { get; set; }
   5: }

 

image

 

Concrete Table Inheritance / Table Per Concrete Type

No table for the base class, each concrete class will have its own table, which will contain columns for all of the class’ properties, including inherited ones. One record will only exist in one of the tables, so usage of IDENTITY columns as primary keys is not possible, because there will be records with the same ID on all of the tables, unless different seeds and/or increments are used.

   1:publicabstractclass Base
   2: {
   3:public Int32 BaseId { get; set; }
   4:  
   5:public String InheritedColumn { get; set; }
   6: }

 

   1: [Table("DerivedA")]
   2:publicclass DerivedA : Base
   3: {
   4:public String ColumnA { get; set; }
   5: }

 

   1: [Table("DerivedB")]
   2:publicclass DerivedB : Base
   3: {
   4:public String ColumnB { get; set; }
   5: }

This will require additional configuration at the context level, this strategy is not possible just with attributes:

   1:publicclass Context : DbContext
   2: {
   3:protectedoverridevoid OnModelCreating(DbModelBuilder modelBuilder)
   4:     {
   5:         modelBuilder.Entity<DerivedA>().Map(m =>
   6:         {
   7:             m.MapInheritedProperties();
   8:         });
   9:         modelBuilder.Entity<DerivedB>().Map(m =>
  10:         {
  11:             m.MapInheritedProperties();
  12:         });
  13:     }
  14:  
  15:public DbSet<Base> Bases { get; set; }
  16: }

 

image


Viewing all articles
Browse latest Browse all 404

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>