1

通过代码优先的方法(但使用现有的数据库模式),我们试图将 2 个不同的实体(客户和资源)映射到同一个表。两个实体具有相同的键和映射。

但是,在运行应用程序时,我们会遇到一个运行时错误,告诉我们这条神秘消息:

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.    

例子:

 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");
    }
}

上面的代码类似于我们的客户/资源代码(但解释更简单!)。但是,得到相同的错误消息,告诉我们 EntityA 和 EntityB 不能映射到同一个表,因为它们的主键名称不匹配。

知道我们的映射有什么问题吗?知道我们如何将不同的实体放到同一个表中吗?

谢谢你的帮助

4

1 回答 1

1

将 2 个实体映射到一个表需要您创建一个Complex TypeTable Per Hierarchy (TPH)。您不能像这样将 2 个实体映射到一张表。让我知道哪一个更能描述您的域模型,我将为您提供所需的对象模型/流式 API 代码。

更新:TPH 映射:

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");
    }
}
于 2011-01-15T17:10:15.573 回答