我正在使用具有代码优先和手动迁移的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<ParentClass>
- {
- public ParentConfiguration()
- {
- Map<Foo>(m =>
- {
- m.Requires("IsActive").HasValue(1);
- m.Requires("Type").HasValue("Foo");
- })
- .ToTable("Parent");
- Map<Bar>(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.<GetModel>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<Parent>()
- .Map<Foo>(...)
- .Map<Bar>(...);
这在4.3中不起作用,而是必须在该实体的EntityConfiguration上进行每个Map调用.所以一个这样的模式:
- modelBuilder.Entity<Foo>()
- .Map<Foo>(...);
- modelBuilder.Entity<Bar>()
- .Map<Bar>(...);
以你的具体情况,这应该是有效的:
- protected override void OnModelCreating(DbModelBuilder modelBuilder)
- {
- modelBuilder.Entity<ParentClass>()
- .ToTable("Parent");
- modelBuilder.Entity<Foo>()
- .Map(m =>
- {
- m.Requires("IsActive").HasValue(1);
- m.Requires("Type").HasValue("Foo");
- });
- modelBuilder.Entity<Bar>()
- .Map(m =>
- {
- m.Requires("IsActive").HasValue(1);
- m.Requires("Type").HasValue("Bar");
- });
- }
(我已经删除了一些通用参数,因为它们不需要,但这并不重要.)
使用显式的EntityConfigurations执行此操作,您将使用以下内容:
- public class ParentConfiguration : EntityTypeConfiguration<ParentClass>
- {
- public ParentConfiguration()
- {
- ToTable("Parent");
- }
- }
- public class FooConfiguration : EntityTypeConfiguration<Foo>
- {
- public FooConfiguration()
- {
- Map(m =>
- {
- m.Requires("IsActive").HasValue(1);
- m.Requires("Type").HasValue("Foo");
- });
- }
- }
- public class BarConfiguration : EntityTypeConfiguration<Bar>
- {
- 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中解决这个问题.