EF4 CTP5, mapping different entities to the same (existing) table
L

1

1

By code-first approach (but with an existing db schema), we are trying to map 2 different entities (Customer and Resource) to the same table. Both entities has the same keys and mapping.

However, when running the app, we have a runtime error telling us that mysterious message:

System.InvalidOperationException: Type 'Resource' cannot be mapped to table 'CLIENT' since type 'Customer' also maps to the same table and their primary key names don't match. Change either of the primary key property names so that they match.    

Example:

 public class EntityA
{
    public string ID { get; set; }
    public string Discriminator { get; set; }
    public string TimeStamp { get; set; }
}
public class EntityB
{
    public string ID { get; set; }
    public string Discriminator { get; set; }
    public string CreatedBy { get; set; }
}
public class EntityAConfiguration : EntityTypeConfiguration<EntityA>
{
    public EntityAConfiguration()
    {
        HasKey(x => new {x.ID, x.Discriminator } );
        Property(x => x.ID).HasColumnName("MyTable_ID").HasDatabaseGenerationOption(DatabaseGenerationOption.None);
        Property(x => x.Discriminator).HasColumnName("MyTable_Discriminator").HasDatabaseGenerationOption(DatabaseGenerationOption.None);            
        Property(x => x.TimeStamp).HasColumnName("MyTable_TimeStamp");
        ToTable("MyTable");
    }
}
public class EntityBConfiguration : EntityTypeConfiguration<EntityB>
{
    public EntityBConfiguration()
    {
        HasKey(x => new { x.ID, x.Discriminator });
        Property(x => x.ID).HasColumnName("MyTable_ID").HasDatabaseGenerationOption(DatabaseGenerationOption.None);
        Property(x => x.Discriminator).HasColumnName("MyTable_Discriminator").HasDatabaseGenerationOption(DatabaseGenerationOption.None);
        Property(x => x.CreatedBy).HasColumnName("MyTable_CreatedBy");
        ToTable("MyTable");
    }
}

The above code is similar to our Customer/Resource code (but simpler for the explanation!). However, get get the same Error message, telling us that EntityA and EntityB cannot be mapped to the same table because their primary key names don't match.

Any idea of what is wrong with our mapping? Any idea how we could different entities to the same table?

Thanks for your help

Lorenza answered 15/1, 2011 at 16:37 Comment(0)
C
1

Mapping 2 entity to one table requires that you create a Complex Type or Table Per Hierarchy (TPH). You can't just map 2 entities to one table like this. Let me know which one is better describe your domain model and I will provide you with the required object model/fluent API code.

Update: TPH Mapping:

public abstract class EntityBase
{
    [Column(Name = "MyTable_ID")]  
    public string ID { get; set; }
    [Column(Name = "MyTable_Discriminator")]  
    public string Discriminator { get; set; }      
}
public class EntityA : EntityBase
{
    [Column(Name = "MyTable_TimeStamp")]
    public string TimeStamp { get; set; }
}
public class EntityB : EntityBase
{
    [Column(Name = "MyTable_CreatedBy")]
    public string CreatedBy { get; set; }
}                
public class StackoverflowTestContext : DbContext
{
    public DbSet<EntityBase> Entities { get; set; }        
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<EntityBase>()
                    .HasKey(x => new { x.ID, x.Discriminator });

        modelBuilder.Entity<EntityBase>()
                    .Map<EntityA>(m => m.Requires("TPHDiscriminator")
                    .HasValue("yourDesiredValueForA"))
                    .Map<EntityB>(m => m.Requires("TPHDiscriminator")
                    .HasValue("yourDesiredValueForB"))
                    .ToTable("MyTable");
    }
}
Cassiani answered 15/1, 2011 at 17:10 Comment(5)
Seems like TPH might be the better option here. With TPH and discriminator, I guess we can make our little example work?Ruder
That's what I thought too. So given that TPH will create a Discriminator column for you, do you still need to have a Discriminator property in your EntityA and EntityB?Cassiani
Nope, we are working on an existing DB schema, that we cannot alter in any way...Ruder
I've updated the answer with a TPH mapping, see how this one works out for you.Cassiani
Thanks... I am trying it in my domain 'à l'instant' :-)Ruder

© 2022 - 2024 — McMap. All rights reserved.