EF4 CTP5,将不同实体映射到相同(现有)表 [英] EF4 CTP5, mapping different entities to the same (existing) table

查看:156
本文介绍了EF4 CTP5,将不同实体映射到相同(现有)表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



但是,运行应用程序时,我们有一个运行时错误告诉我们这个神秘的消息:

  System.InvalidOperationException:键入'资源'不能映射到表'CLIENT',因为类型'客户'也映射到同一个表,并且它们的主键名称' t比赛。更改主键属性名称以使其匹配。 

示例:

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

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



我们的映射有什么问题的想法?
任何想法我们如何将不同的实体移动到同一个表?



感谢您的帮助

解决方案

将2个实体映射到一个表需要创建一个。你不能将这两个实体映射到一个表。让我知道哪一个更好地描述你的领域模型,我将为您提供所需的对象模型/流畅的API代码。



更新:TPH映射:



  public abstract class EntityBase 
{
[Column(Name =MyTable_ID)]
public string ID {get;组; }
[Column(Name =MyTable_Discriminator)]
public string Discriminator {get;组; }
}
public class EntityA:EntityBase
{
[Column(Name =MyTable_TimeStamp)]
public string TimeStamp {get;组; }
}
public class EntityB:EntityBase
{
[Column(Name =MyTable_CreatedBy)]
public string CreatedBy {get;组; }
}
public class StackoverflowTestContext:DbContext
{
public DbSet< EntityBase>实体{get;组;
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);
}
}


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

解决方案

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

这篇关于EF4 CTP5,将不同实体映射到相同(现有)表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆