我有一个表层次结构,其中包含每个混凝土类型(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; }
}
当Id
和Page
实体的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映射描述这样的配置?
任何其他解决方案提案都会有所帮助。
答案 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);
}
}