实体框架代码首先多对多关系和继承

时间:2013-03-27 15:02:51

标签: asp.net-mvc-4 ef-code-first entity-framework-5

请原谅我,如果这个问题已在某个地方得到解答,我一直很难找到解决这个问题的方法。

我正在尝试在MVC4项目上设置EF Code First。我有一个继承自Person的用户和客户。然后我有一个Template对象,它与Customer有多对多的关系,与User有一对多的关系。以下是我设置的方法:

模型

public class Person
{
    [Key]
    public int PersonID { get; set; }

    public string LastName { get; set; }
    public string FirstName { get; set; }

    public string FullName
    {
        get
        {
            return String.Format("{0} {1}", FirstName, LastName);
        }
    }

    public string Email { get; set; }

    public virtual List<Template> Templates { get; set; }
}

public class User : Person
{
    .... 
}

public class Customer : Person
{
    ....
}

public class Template
{
    public int TemplateId { get; set; }
    public string TemplateName { get; set; }

    public virtual List<Customer> Customers { get; set; }

    [ForeignKey("User")]
    public int UserId { get; set; }
    public virtual User User { get; set; }
}

CONTEXT

public class ProjectContext : DbContext
{
    public ProjectContext()
        : base("name=ProjectDB")
    {
    }

    public DbSet<Template> Templates { get; set; }
    public DbSet<User> Users { get; set; }
    public DbSet<Customer> Customers { get; set; }
    public DbSet<Person> People { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions
            .Remove<PluralizingTableNameConvention>();

        modelBuilder.Entity<Template>()
            .HasMany(x => x.Customers)
            .WithMany(x => x.Templates)
            .Map(x => x.MapLeftKey("TemplateId")
                .MapRightKey("PersonId")
                .ToTable("TemplateCustomer")
            );
    }
}

如果我从上下文中移除Person DBSet,这可以正常工作但设置TPT继承。我想使用TPH继承,但是当我在上下文中使用Person DBSet启用迁移时,它会阻塞:

NavigationProperty“模板”无效。在AssociationType'MvcProject.Models.Template_Customers'中键入FromRole'Template_Customers_Target'的'MvcProject.Models.Customer'必须与声明此NavigationProperty的类型'MvcProject.Models.Person'完全匹配。

我在哪里错了?

2 个答案:

答案 0 :(得分:14)

您无法从基础实体继承导航属性。它们总是必须在关系的另一端引用的类中声明

  • Template.Customers引用Customer(不是Person),因此反向导航属性Templates必须在Customer中声明(不在{{}} 1}})
  • Person引用Template.User(不是User),因此反向导航属性Person必须在Templates中声明(不在{{}} 1}})

所以,基本上你必须将User集合从Person移到两个派生类中:

Templates

然后您可以使用Fluent API定义两个关系,如下所示:

Person

答案 1 :(得分:0)

将HasMany选择器更改为People:

    modelBuilder.Entity<Template>()
        .HasMany(x => x.People) // here
        .WithMany(x => x.Templates)
        .Map(x => x.MapLeftKey("TemplateId")
            .MapRightKey("PersonId")
            .ToTable("TemplateCustomer")
        );
相关问题