mron
mron

Reputation: 95

EF different mapping for an entity based on inheritance

I have two entities (tables) Action and ActionLog. The ActionLog is derived from Action. I need to map entity Action to table Action when it is used alone and map it to table ActionLog when it is used inside an inheritance relationship.

Entities:

Action entity properties:

ActionLog entity properties:

Tables:

Action table columns:

ActionLog table columns:

Is this possible using EF6 Code First mapping in a single context?

Edit 1:

I try to be more explicit. I need something like this:

using(var ctx = new DbContext())
{
    var action = new Action 
    { 
        Action_Property1 = 1,
        Action_Property2 = 2,
        Action_Property3 = 3
    };
    ctx.Actions.Add(action);
    ctx.SaveChanges();
}

The lines above should write the Action entity to Action table.

using(var ctx = new DbContext())
{
    var actionLog = new ActionLog 
    { 
        Action_Property1 = 1,
        Action_Property2 = 2,
        Action_Property3 = 3,
        ActionLog_Property1 = 1
    };
    ctx.ActionLogs.Add(actionLog);
    ctx.SaveChanges();
}

The lines above should write the ActionLog entity to ActionLog table.

Upvotes: 2

Views: 253

Answers (2)

Robert Goldwein
Robert Goldwein

Reputation: 6021

Sure, map your base class:

public class YourBaseClassMapping<T> : EntityTypeConfiguration<T> where T : YourBaseClassEntity
{
    protected YourBaseClassMapping()
    {
        HasKey(x => x.Id);
        ...
    }
}

and then map inherited class:

public class InheritedClassMapping<T> : EntityTypeConfiguration<T> where T : InheritedClassMapping
{
    public InheritedClassMapping()
    {
        // new mapping for inherited class
    }        
}

and add both mappings to DbModelBuilder as other mappings:

public class YourDbContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new YourBaseClassMapping());
        modelBuilder.Configurations.Add(new InheritedClassMapping());
    }
}

Upvotes: 0

Alexcei Shmakov
Alexcei Shmakov

Reputation: 2353

Yes, it's possible. Using Mapping the Table-Per-Concrete Class (TPC) Inheritance it can do so

public class InheritanceMappingContext : DbContext
{
    public DbSet<Action> Action { get; set; }
    public DbSet<ActionLog> ActionLog { get; set; }


    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<ActionLog>().Map(m =>
        {
            m.MapInheritedProperties(); // add inherited property to actionLog
            m.ToTable("ActionLog");
        });

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

Upvotes: 1

Related Questions