Eric J.
Eric J.

Reputation: 150108

Error Remapping EF Code First TPH Discriminator

I'm attempting to remap the descriminator column of my TPH-persisted object hierarchy as described at:

http://msdn.microsoft.com/en-us/library/hh295845(v=vs.103).aspx

http://blogs.msdn.com/b/adonet/archive/2010/12/14/ef-feature-ctp5-fluent-api-samples.aspx

https://stackoverflow.com/a/6650064/141172

When I map using either of the following variants:

modelBuilder.Entity<MyBase>()
            .Map<MyBase>(m => m.Requires("TypeId").HasValue(0))
            .Map<DerivedA>(m => m.Requires("TypeId").HasValue(1))
            .Map<DerivedB>(m => m.Requires("TypeId").HasValue(2))
            .Map<DerivedC>(m => m.Requires("TypeId").HasValue(3))
            .Map<DerivedD>(m => m.Requires("TypeId").HasValue(4));

or

modelBuilder.Entity<MyBase>()
            .Map<MyBase>(m => m.Requires("TypeId").HasValue(0));
modelBuilder.Entity<MyBase>()
            .Map<DerivedA>(m => m.Requires("TypeId").HasValue(1));
modelBuilder.Entity<MyBase>()
            .Map<DerivedB>(m => m.Requires("TypeId").HasValue(2));
modelBuilder.Entity<MyBase>()
            .Map<DerivedC>(m => m.Requires("TypeId").HasValue(3));
modelBuilder.Entity<MyBase>()
            .Map<DerivedD>(m => m.Requires("TypeId").HasValue(4));

With the following variations:

I get the error:

Map was called more than once for type 'DerivedA' and at least one of the calls didn't specify the target table name.

All derived classes inherit directly from MyBase, and all derived classes are included in the mapping.

I'm using Entity Framework 4.3.1.

What am I doing wrong?

Upvotes: 3

Views: 1677

Answers (1)

Arthur Vickers
Arthur Vickers

Reputation: 7523

This is fixed in EF5-beta2 where the chained Map calls should work.

In EF 4.3 you will need to split out each Map call onto an EntityTypeConfiguration for the entity type to which it applies.

modelBuilder.Entity<MyBase>() 
        .Map<MyBase>(m => m.Requires("TypeId").HasValue(0)); 
modelBuilder.Entity<DerivedA>() 
        .Map<DerivedA>(m => m.Requires("TypeId").HasValue(1)); 
modelBuilder.Entity<DerivedB>() 
        .Map<DerivedB>(m => m.Requires("TypeId").HasValue(2)); 
modelBuilder.Entity<DerivedC>() 
        .Map<DerivedC>(m => m.Requires("TypeId").HasValue(3)); 
modelBuilder.Entity<DerivedD>() 
        .Map<DerivedD>(m => m.Requires("TypeId").HasValue(4)); 

Notice the calls to Entity<DerivedA>, Entity<DerivedB>, and so on rather than all to Entity<MyBase>.

Upvotes: 7

Related Questions