实体框架如何不映射类,但确实映射了它的继承属性

时间:2014-08-01 10:43:40

标签: entity-framework ef-code-first mapping

我们在Web mvc应用程序(StdWebApp)中使用EntityFramework 6.1和CodeFirst。现在我们要创建此应用程序的新自定义版本(CustomWebApp)。 applications overview CustomWebApp将使用标准的大部分代码,在它的域模型中它将扩展Person类。 在CustomDomain中,我们为实现一个新的DbContext,它必须与自定义应用程序的数据库(CustomSqlDb)连接。

在(C#)代码中,在域和CustomDomain中存在Person,这是没有问题的。但是,我们无法在Custom DbContext中为Person设计一个映射:

  1. 创建一个“人员”表。
  2. 包含“CustomDomain.Person”字段和“Domain.Person”中的字段。
  3. 我们尝试了一些这样的变体:

       modelBuilder.Entity<Person>().Map(m =>
            {
                m.MapInheritedProperties();
                m.ToTable("Person");
            }
       );
    

    使用此文档作为我们的灵感msdn mapping types

    但EF抱怨简单的名字相同。 显然我们可以将“CustomDomain”中的“Person”重命名为“PersonCustom”,但是如果我们将来必须再次这样做,可能会导致很多愚蠢的名字,如“PersonCustomExtraSpecial”等。

    有人想到吗?

    更新

    我们尝试了mr100建议的解决方案,这里是完整的代码:

    namespace Domain
    {
    
        public class Person
        {
           public int Id { get; set; }
           public string Stuff { get; set; }
        }
    }
    
    namespace CustomDomain
    {   
        public class Person : Domain.Person
        {
          public string ExtraStuff { get; set; }
        }
    }
    
    namespace CustomDomain
    {
        public class DbModel : DbContext
        {
           DbSet<CustomDomain.Person> Persons { get; set; }
           protected override void OnModelCreating(DbModelBuilder modelBuilder)
           {
               modelBuilder.Entity<CustomDomain.Person>().Map(m => m.ToTable("Person"));
           }
        }
    }
    

    这仍然会导致错误

      

    “CustomDomain.Person”类型和“Domain.Person”类型都具有相同的简单名称“Person”,因此不能在同一模型中使用。给定模型中的所有类型都必须具有唯一的简单名称。使用'NotMappedAttribute'或在Code First Fluent API中调用Ignore,以明确地从模型中排除属性或类型。

    所以我们添加了以下代码:

    namespace CustomDomain
    {
        public class DbModel : DbContext
        {
            DbSet<CustomDomain.Person> Persons { get; set; }
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
               modelBuilder.Ignore<Domain.Person>();
               modelBuilder.Entity<CustomDomain.Person>().Map(m => m.ToTable("Person"));
            }
        }
    }
    

    仍然是相同的结果。

1 个答案:

答案 0 :(得分:0)

要实现此目的,CustomWebApps中的DbContext类应具有以下定义的属性:

public DbSet<CustomDomain.Person> People {get; set;}

且没有财产:

public DbSet<Domain.Person> People {get; set;}

即使它来自可能派生CustomWebApp DbContext类的StdWebApp DbContext类(如果是这种情况)。另外,您可以正确设置表名:

modelBuilder.Entity<Person>().ToTable("Person");