实体框架4.3 - TPH映射和迁移错误 [英] Entity Framework 4.3 - TPH mapping and migration error

查看:325
本文介绍了实体框架4.3 - TPH映射和迁移错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用实体框架4.3 code第一和手动迁移。我试图映射TPH(表每个层次结构)设置,其中使用了两个自定义鉴别领域。一个用于鉴别器本身,另一个用于软删除(很像在NH类的映射的,其中选项)。完全相同的设置工作只是正常的运行在EF 4.2的另一个项目。

I'm using Entity Framework 4.3 with code first and manual migrations. I'm trying to map a TPH (table-per-hierarchy) setup which uses two custom discriminator fields. One for the discriminator itself and the other for soft deletes (much like the "where" option in NH class mappings). The exact same setup works just fine in another project which runs on EF 4.2.

我尝试添加了的NuGet控制台使用添加迁移命令迁移时出现错误。我试图定义表名的所有组合 - 属性的类,在OnModelCreating的方法,在等我的previous迁移不涉及复杂的层次结构的映射已经工作就好EntityTypeConfiguration班

I get the error when trying to add a migration using the "add-migration" command in the NuGet console. I have tried all combinations of defining the table name - attributes on class, in "OnModelCreating" method, in EntityTypeConfiguration classes etc. My previous migrations which didn't involve complex hierarchy mappings have worked just fine.

是否有EF 4.3有一些重大的变化时,我已经迷迷糊糊?

Is there some breaking change in EF 4.3 that I've stumbled upon?

在code:

//---- 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

Mihkel

推荐答案

这是一个已知的问题4.3和4.3.1。 (我们发现为时已晚把补丁4.3.1)。幸运的是有一个相当简单的方法来改变你的code,应该使它发挥作用。

This is a known issue with 4.3 and 4.3.1. (We found it too late to put the fix in 4.3.1.) Luckily there is a fairly simple way to change your code that should make it work.

在简单地说,你曾经是能够在4.1上一个EntityConfiguration使链式地图调用。和4.2。事情是这样的模式:

In a nutshell, you used to be able to make chained map calls on a single EntityConfiguration in 4.1. and 4.2. Something like this pattern:

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

这并不4.3工作,而是你必须做出一个EntityConfiguration该实体每个地图调用。因此,一个模式是这样的:

This doesn't work in 4.3 and instead you have to make each Map call on an EntityConfiguration for that entity. So a pattern something like this:

modelBuilder.Entity<Foo>()
   .Map<Foo>(...);

modelBuilder.Entity<Bar>()
   .Map<Bar>(...);

以你的情况下,具体地讲,这应该工作:

Taking your case specifically, this should work:

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");
                });
}

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

(I've removed a few of the generic parameters since they aren't needed, but that's not important.)

这样做使用明确EntityConfigurations你会使用这样的:

Doing this using explicit EntityConfigurations you would use something like this:

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。

We plan to fix this in 5.0.

这篇关于实体框架4.3 - TPH映射和迁移错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆