c# – 实体框架4.3 – TPH映射和迁移错误

前端之家收集整理的这篇文章主要介绍了c# – 实体框架4.3 – TPH映射和迁移错误前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用具有代码优先和手动迁移的Entity Framework 4.3.我正在尝试映射一个使用两个自定义标识符字段的TPH(每层次表格)设置.一个用于鉴别器本身,另一个用于软删除(非常类似于NH类映射中的“where”选项).在EF 4.2运行的另一个项目中,完全相同的设置正常工作.

尝试使用NuGet控制台中的“add-migration”命令添加迁移时,我收到错误.我尝试了在“OnModelCreating”方法,EntityTypeConfiguration类等中定义表名称属性的所有组合.我以前的迁移不涉及复杂的层次结构映射已经很好了.

EF 4.3中有一些突破性的变化,我偶然发现了吗?

代码

  1. //---- Domain classes ---------------------
  2.  
  3. public abstract class ParentClass
  4. {
  5. public string ParentString { get; set; }
  6. }
  7.  
  8. public class Foo : ParentClass
  9. {
  10. public string FooString { get; set; }
  11. }
  12.  
  13. public class Bar : ParentClass
  14. {
  15. public string BarString { get; set; }
  16. }
  17.  
  18. //---- Mapping configuration --------------
  19.  
  20. public class ParentConfiguration : EntityTypeConfiguration<ParentClass>
  21. {
  22. public ParentConfiguration()
  23. {
  24. Map<Foo>(m =>
  25. {
  26. m.Requires("IsActive").HasValue(1);
  27. m.Requires("Type").HasValue("Foo");
  28. })
  29. .ToTable("Parent");
  30.  
  31. Map<Bar>(m =>
  32. {
  33. m.Requires("IsActive").HasValue(1);
  34. m.Requires("Type").HasValue("Bar");
  35. })
  36. .ToTable("Parent");
  37. }
  38. }
  39.  
  40. //---- Context ----------------------------
  41.  
  42. protected override void OnModelCreating(DbModelBuilder modelBuilder)
  43. {
  44. modelBuilder.Configurations.Add(new ParentConfiguration());
  45. }

错误

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

Mihkel

解决方法

这是4.3和4.3.1的已知问题. (我们发现在4.3.1中解决了这个问题太晚了)幸运的是,有一个相当简单的方法来改变应该使其工作的代码.

简而言之,您曾经能够在4.1中的单个EntityConfiguration上进行链接映射调用.和4.2.像这样的样子:

  1. modelBuilder.Entity<Parent>()
  2. .Map<Foo>(...)
  3. .Map<Bar>(...);

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

  1. modelBuilder.Entity<Foo>()
  2. .Map<Foo>(...);
  3.  
  4. modelBuilder.Entity<Bar>()
  5. .Map<Bar>(...);

以你的具体情况,这应该是有效的:

  1. protected override void OnModelCreating(DbModelBuilder modelBuilder)
  2. {
  3. modelBuilder.Entity<ParentClass>()
  4. .ToTable("Parent");
  5.  
  6. modelBuilder.Entity<Foo>()
  7. .Map(m =>
  8. {
  9. m.Requires("IsActive").HasValue(1);
  10. m.Requires("Type").HasValue("Foo");
  11. });
  12.  
  13. modelBuilder.Entity<Bar>()
  14. .Map(m =>
  15. {
  16. m.Requires("IsActive").HasValue(1);
  17. m.Requires("Type").HasValue("Bar");
  18. });
  19. }

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

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

  1. public class ParentConfiguration : EntityTypeConfiguration<ParentClass>
  2. {
  3. public ParentConfiguration()
  4. {
  5. ToTable("Parent");
  6. }
  7. }
  8.  
  9. public class FooConfiguration : EntityTypeConfiguration<Foo>
  10. {
  11. public FooConfiguration()
  12. {
  13. Map(m =>
  14. {
  15. m.Requires("IsActive").HasValue(1);
  16. m.Requires("Type").HasValue("Foo");
  17. });
  18. }
  19. }
  20.  
  21. public class BarConfiguration : EntityTypeConfiguration<Bar>
  22. {
  23. public BarConfiguration()
  24. {
  25. Map(m =>
  26. {
  27. m.Requires("IsActive").HasValue(1);
  28. m.Requires("Type").HasValue("Bar");
  29. });
  30. }
  31. }

接着

  1. protected override void OnModelCreating(DbModelBuilder modelBuilder)
  2. {
  3. modelBuilder.Configurations
  4. .Add(new ParentConfiguration())
  5. .Add(new FooConfiguration())
  6. .Add(new BarConfiguration());
  7. }

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

猜你在找的C#相关文章