每个具体类型的表(TPC)与EF6中的Composite键映射

时间:2016-11-23 09:17:50

标签: c# entity-framework entity-framework-6 composite-key

我有一个表层次结构,其中包含每个混凝土类型(TPC)映射表。 (我不确定[Key,Column]属性是否必要,但根据https://stackoverflow.com/a/19792915/959779它应该有效)

班级结构:

public abstract class BaseEntity
{
    [Key, Column(Order = 0)]
    public int Id { get; set; }
}
public class Page: BaseEntity {
    string Data { get; set; }
}
public class PageBackup: Page {
    [Key, Column(Order = 1)]
    public int PageId { get; set; }
    public virtual Page Page { get; set; }
}

IdPage实体的PageBackup相交时(在向表添加某些项目之后),EF会抛出下一次执行

  

“EntitySet中的所有对象'EUICDataContext.Pages'必须具有唯一的主键。   但是,类型为'Entities.PageBackup'的实例和类型的实例   'Entities.Page'都具有相同的主键值'EntitySet = Pages; Id = 6'。 “

实体映射代码如下:

class PageMapping : EntityTypeConfiguration<Page> 
{
    public PageMapping ()
    {
        Map(m =>{ m.ToTable("Page"); });
        HasKey(t => t.Id });
    }
}

class PageBackupMapping : EntityTypeConfiguration<PageBackup> 
{
    public PageBackupMapping ()
    {
        Map(m =>{
            m.MapInheritedProperties();
            m.ToTable("PageBackup");
        });
        HasKey(t => new { t.Id, t.PageId });
    }
 }

问题是虽然在EF PageMapping中有复合键Update-Database种子脚本创建具有下一个签名的表:

CREATE TABLE [dbo].[PageBackup](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [PageId] [int] NOT NULL,
    [Data] [nvarchar](max) NULL,
    CONSTRAINT [PK_dbo.PageBackup] PRIMARY KEY CLUSTERED 
    (
            [Id] ASC
    )

EF是否允许使用复合键创建表(很多示例都带有映射,但我没有发现任何有关迁移的内容)?

如何代表TPC映射描述这样的配置?

任何其他解决方案提案都会有所帮助。

1 个答案:

答案 0 :(得分:1)

我正在玩它,看起来这种情况不受EF 6的支持。我的迁移是使用Id主键自动生成的。

  CreateTable(
            "dbo.PageBackUp",
            c => new
                {
                    Id = c.Int(nullable: false),
                    PageId = c.Int(nullable: false),
                })
            .PrimaryKey(t => t.Id);

之后我尝试在EF Core 1.1.0上管理这个。我遇到了一个错误

  

无法在&#39; Page&#39;因为它是派生类型。该   必须在根类型&#39; BaseEntity&#39;上配置密钥。如果你没有   打算“BaseEntity&#39;要包含在模型中,请确保它是   不包含在上下文中的DbSet属性中,在a中引用   配置调用ModelBuilder,或从导航引用   属性中包含的类型的属性。

我认为这是实体框架的限制。您可以通过此问题向EF repo提出问题。

我的EF核心配置是:

public class ProductContext : DbContext
{
    public ProductContext()
    {

    }
    public ProductContext(DbContextOptions<ProductContext> options)
        : base(options)
    { }

    public DbSet<Page> Page { get; set; }
    public DbSet<PageBackup> PageBackup { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder builder)
    {
        builder.UseSqlServer("Data Source=.\\sqlexpress;");
        base.OnConfiguring(builder);
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Page>()
            .HasBaseType<BaseEntity>()
            .ToTable("Page")
            .HasKey(t => t.Id);

        modelBuilder.Entity<PageBackup>()
            .HasBaseType<Page>()
            .HasKey(t => new { t.PageId, t.Id });

        base.OnModelCreating(modelBuilder);
    }
}

EF 6版本:

public class ProductContext : DbContext
{
    public DbSet<Page> Page { get; set; }
    public DbSet<PageBackup> PageBackup { get; set; }


    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Page>()
            .Map(m => m.MapInheritedProperties().ToTable("Page"))
            .HasKey(t => t.Id);


        modelBuilder.Entity<PageBackup>()
            .Map(m => m.MapInheritedProperties().ToTable("PageBackUp"))
            .HasKey(t => new { t.PageId, t.Id });

        base.OnModelCreating(modelBuilder);
    }
}