c# - Entity Framework 4.3 - TPH 映射和迁移错误

标签 c# .net entity-framework database-migration entity-framework-4.3

我使用 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()

米克尔

最佳答案

这是 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 中修复此问题。

关于c# - Entity Framework 4.3 - TPH 映射和迁移错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9499702/

相关文章:

.net - 动态设置 RDLC 报告中的图像源

.net - Wix - 自定义安装目录

c# - Entity Framework : one or more of the foreign-key properties is non-nullable

c# - 按 Linq 子集合中的最小值排序父集合

c# - 可以设置RequestValidationMode ="2.0"页面级别吗?

javascript - 页面繁忙图标仅在单击按钮时显示

c# - 强制服务中的线程等待另一个线程完成

c# - 无法在 asp.net View 中显示来自数据库的图像

c# - 缓存静态表 Mysql

c# - SerialPort UnauthorizedAccessException