entity framework4.3 – TPH映射和迁移错误

我正在使用Entity Framework 4.3,首先是代码迁移和手动迁移。 我正在尝试映射使用两个自定义鉴别器字段的TPH(每层次表)设置。 一个用于鉴别器本身,另一个用于软删除(很像NH类映射中的“where”选项)。 完全相同的设置在另一个在EF 4.2上运行的项目中运行正常。

尝试使用NuGet控制台中的“add-migration”命令添加迁移时出现错误。 我已经尝试了定义表名的所有组合 – 类的属性,“OnModelCreating”方法,EntityTypeConfiguration类等。我以前的迁移不涉及复杂的层次结构映射已经正常工作。

我偶然发现了EF 4.3中的一些重大变化吗?

代码:

//---- Domain classes --------------------- public abstract class ParentClass { public string ParentString { get; set; } } public class Foo : ParentClass { public string FooString { get; set; } } public class Bar : ParentClass { public string BarString { get; set; } } //---- Mapping configuration -------------- public class ParentConfiguration : EntityTypeConfiguration { public ParentConfiguration() { Map(m => { m.Requires("IsActive").HasValue(1); m.Requires("Type").HasValue("Foo"); }) .ToTable("Parent"); Map(m => { m.Requires("IsActive").HasValue(1); m.Requires("Type").HasValue("Bar"); }) .ToTable("Parent"); } } //---- Context ---------------------------- protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Configurations.Add(new ParentConfiguration()); } 

错误:

 System.InvalidOperationException: The type 'Foo' has already been mapped to table 'Parent'. Specify all mapping aspects of a table in a single Map call. at System.Data.Entity.ModelConfiguration.Configuration.Types.EntityTypeConfiguration.AddMappingConfiguration(EntityMappingConfiguration mappingConfiguration) at System.Data.Entity.ModelConfiguration.Configuration.ModelConfiguration.ReassignSubtypeMappings() at System.Data.Entity.DbModelBuilder.Build(DbProviderManifest providerManifest, DbProviderInfo providerInfo) at System.Data.Entity.DbModelBuilder.Build(DbConnection providerConnection) at System.Data.Entity.Infrastructure.EdmxWriter.WriteEdmx(DbContext context, XmlWriter writer) at System.Data.Entity.Migrations.Extensions.DbContextExtensions.c__DisplayClass1.b__0(XmlWriter w) at System.Data.Entity.Migrations.Extensions.DbContextExtensions.GetModel(Action`1 writeXml) at System.Data.Entity.Migrations.Extensions.DbContextExtensions.GetModel(DbContext context) at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration, DbContext usersContext) at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration) at System.Data.Entity.Migrations.Design.ToolingFacade.BaseRunner.GetMigrator() at System.Data.Entity.Migrations.Design.ToolingFacade.GetPendingMigrationsRunner.RunCore() at System.Data.Entity.Migrations.Design.ToolingFacade.BaseRunner.Run() 

Mihkel

这是4.3和4.3.1的已知问题。 (我们发现将修复程序放在4.3.1中为时已晚。)幸运的是,有一种相当简单的方法可以更改代码,使其工作。

简而言之,您曾经能够在4.1中的单个EntityConfiguration上进行链式地图调用。 和4.2。 像这样的模式:

 modelBuilder.Entity() .Map(...) .Map(...); 

这在4.3中不起作用,而是必须在该实体的EntityConfiguration上进行每个Map调用。 所以这样的模式:

 modelBuilder.Entity() .Map(...); modelBuilder.Entity() .Map(...); 

专门针对您的情况,这应该工作:

 protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity() .ToTable("Parent"); modelBuilder.Entity() .Map(m => { m.Requires("IsActive").HasValue(1); m.Requires("Type").HasValue("Foo"); }); modelBuilder.Entity() .Map(m => { m.Requires("IsActive").HasValue(1); m.Requires("Type").HasValue("Bar"); }); } 

(我删除了一些通用参数,因为它们不需要,但这并不重要。)

使用显式EntityConfiguration执行此操作,您将使用以下内容:

 public class ParentConfiguration : EntityTypeConfiguration { public ParentConfiguration() { ToTable("Parent"); } } public class FooConfiguration : EntityTypeConfiguration { public FooConfiguration() { Map(m => { m.Requires("IsActive").HasValue(1); m.Requires("Type").HasValue("Foo"); }); } } public class BarConfiguration : EntityTypeConfiguration { public BarConfiguration() { Map(m => { m.Requires("IsActive").HasValue(1); m.Requires("Type").HasValue("Bar"); }); } } 

然后

 protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Configurations .Add(new ParentConfiguration()) .Add(new FooConfiguration()) .Add(new BarConfiguration()); } 

我们打算在5.0中解决这个问题。