Entity Framework Table Per Class Inheritance

c# entity-framework entity-framework-6 inheritance sql

Question

I am trying to implement a history table for an entity in EF6, code first.

I figured there would be a way to do this with inheritance. The history table, which is a derived type of the actual table entity, just containing straight copies of all the properties. Along with an edit to the key.

My code first table entity config for Booking.

public class BookingEntityConfiguration
    : EntityTypeConfiguration<Booking>
{
    public BookingEntityConfiguration()
    {
        Property(b => b.BookingId).HasColumnOrder(0);
        HasKey(b => new { b.BookingId });

        HasOptional(b => b.BookingType)
            .WithMany()
            .HasForeignKey(c => c.BookingTypeId);
    }
}

My code first table entity config for BookingHistory.

public class BookingHistoryTypeEntityConfiguration
    : EntityTypeConfiguration<BookingHistory>
{
    public BookingHistoryTypeEntityConfiguration()
    {
        Property(b => b.BookingId).HasColumnOrder(0);
        Property(b => b.BookingVersion).HasColumnOrder(0);
        HasKey(b => new { b.BookingId, b.BookingVersion });
    }
}

Where

public class BookingHistory : Booking { }

My BookingHistory table never gets generated in the contexts associated database, which includes these references to the table entities:

public DbSet<Booking> Bookings { get; set; }
public DbSet<BookingHistory> BookingHistories { get; set; }

Is there any simple way to achieve what I want? Which is the derived entity (history table) generates a table that contains the same column fields as the base class entity, but with a change of key.

I appreciate my code above is pretty naive, but I can't seem to find a blog post of similar to help.

1
1
10/10/2014 8:47:15 AM

Accepted Answer

The best way is to have a base type from which both the entity and its history entity inherit:

public class BookingsContext : DbContext
{

    public DbSet<Booking> Bookings { get; set; }
    public DbSet<BookingHistory> BookingHistories { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<BookingBase>()
            .HasKey(p => p.BookingId)
            .Property(p => p.BookingId)
                       .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        modelBuilder.Entity<Booking>().Map(m =>
            {
                m.MapInheritedProperties();
                m.ToTable("Booking");
            });

        modelBuilder.Entity<BookingHistory>().Map(m =>
            {
                m.MapInheritedProperties();
                m.ToTable("BookingHistory");
            });
    }
}

By ToTable you specify that both entities should be mapped to different tables. On top of that, MapInheritedProperties tells EF to mapp all properties from the base type to this table as well. the result is two completely independent tables that can be addressed by two separate DbSet properties.

1
10/10/2014 3:19:02 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow