【问题标题】:EntityFramework how to not map a class but do map it's inherited propertiesEntityFramework 如何不映射一个类但映射它的继承属性
【发布时间】:2014-09-24 13:17:56
【问题描述】:

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

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

  1. 创建一个“Person”表。
  2. 包含“CustomDomain.Person”和“Domain.Person”中的字段。

我们尝试了一些这样的变体:

   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”,因此不能在同一模型中使用。给定模型中的所有类型都必须具有唯一的简单名称。在 Code First fluent API 中使用“NotMappedAttribute”或调用 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"));
        }
    }
}

还是一样的结果。

【问题讨论】:

  • @Humayun 很棒的编辑 ;-)

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


【解决方案1】:

要实现这一点,您在 CustomWebApps 中的 DbContext 类应该具有这样定义的属性 People:

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

没有财产:

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

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

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

【讨论】:

  • 我们尝试了您的回答,查看更新后的问题,但仍然遇到同样的错误。如果它对您有用,您可以在答案中包含示例代码吗?
  • 不幸的是,当前版本的 EF 无法实现您要实现的目标。 EF 不识别命名空间,并且它始终包含模型的基本类型,您无法使用 Ignore 将其删除。检查此链接以供参考:stackoverflow.com/questions/18638741/… Guys there 声明 EF 团队最终将在第 7 版中删除此限制。现在恐怕您问题的唯一解决方案是将 Domain.Person 或 CustomDomain.Person 类重命名为不同的名称。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-01
  • 2016-08-29
  • 1970-01-01
  • 1970-01-01
  • 2013-03-04
相关资源
最近更新 更多