通过代码优先方法(但使用现有的db模式),我们尝试将2个不同的实体(Customer和Resource)映射到同一个表。两个实体都具有相同的键和映射。
然而,在运行应用程序时,我们遇到运行时错误,告诉我们这条神秘的消息:
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无法映射到同一个表,因为它们的主键名称不匹配。
我们的映射有什么问题吗? 知道我们如何将不同的实体放在同一张桌子上吗?
感谢您的帮助
答案 0 :(得分:1)
将2个实体映射到一个表格需要您创建Complex Type或Table Per Hierarchy (TPH)。您不能像这样将2个实体映射到一个表。让我知道哪一个更好地描述您的域模型,我将为您提供所需的对象模型/流畅的API代码。
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");
}
}