实体框架code首先多到多关系和继承 [英] Entity Framework Code First Many-to-Many relationship and inheritance

查看:118
本文介绍了实体框架code首先多到多关系和继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

原谅我,如果这个问题已经回答了什么地方,我一直有一个很难找到这个问题的解决方案。

Forgive me if this question has been answered somewhere, I have been having a hard time finding a solution for this problem.

我试图建立EF code首先在一个MVC4项目。我有一个用户和客户,无论从Person继承。然后,我有一个与客户多对多关系,并与用户的一到多关系模板对象。这是我如何有它设置:

I am trying to set up EF Code First on an MVC4 Project. I have a User and Customer that both inherit from Person. I then have a Template object that has a Many-to-Many relationship with Customer and a One-to-Many relationship with User. Here is how I have it set up:

模型

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

背景

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

如果我删除的人DBSet出的背景下能正常工作,但设置了TPT的继承。我想用TPH继承,但是当我能在上下文的人DBSet迁移它闷死了:

If I remove the Person DBSet out of the context this works fine but sets up TPT inheritance. I would like to use TPH inheritance, but when I enable migrations with the Person DBSet in the context it chokes:

NavigationProperty'模板'是无效的。 FromRole在AssociationTypeMvcProject.Models.Template_Customers'Template_Customers_Target'类型'MvcProject.Models.Customer必须完全匹配与此NavigationProperty声明的类型'MvcProject.Models.Person'。

NavigationProperty 'Templates' is not valid. Type 'MvcProject.Models.Customer' of FromRole 'Template_Customers_Target' in AssociationType 'MvcProject.Models.Template_Customers' must exactly match with the type 'MvcProject.Models.Person' on which this NavigationProperty is declared on.

我在哪里去错在这里?

推荐答案

您不能继承的从基实体导航属性的。他们总是必须的声明的关系中的另一端指的是类。

You cannot inherit navigation properties from a base entity. They always must be declared in the class the other end of the relationship is refering to.


  • Template.Customers 是指的客户(不是),因此逆导航属性模板必须在客户(不是

  • Template.User 是指的用户(不是),因此逆导航属性模板必须在用户(不是

  • Template.Customers is refering to Customer (not to Person), hence the inverse navigation property Templates must be declared in Customer (not in Person)
  • Template.User is refering to User (not to Person), hence the inverse navigation property Templates must be declared in User (not in Person)

所以,基本上,你必须从移动模板收集到两个派生类:

So, basically you must move the Templates collection from Person into both derived classes:

public class Person
{
    // no Templates collection here
}

public class User : Person
{
    //... 
    public virtual List<Template> Templates { get; set; }
}

public class Customer : Person
{
    //...
    public virtual List<Template> Templates { get; set; }
}

然后,你可以定义像这样流利的API的两个关系:

Then you can define the two relationships with Fluent API like so:

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

modelBuilder.Entity<Template>()
    .HasRequired(t => t.User)
    .WithMany(u => u.Templates) // = User.Templates
    .HasForeignKey(t => t.UserId);

这篇关于实体框架code首先多到多关系和继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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