本文介绍了EF同一主键上有多个外键关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用EF 6通过代码优先的方法创建多对多关系.我的实体使用复合主键(以处理多租户).

I want to create a many-to-many relationship using EF 6 using a code-first approach. My entities use a composite primary key (to handle multi-tenancy).

让我们举一个简单而经典的例子.我有两个实体ProjectPerson具有多对多关系:

Let's take simple and classical example. I have two entities Project and Person which have a many-to-many relationship:

public class Person
{
   [Key, Column(Order = 1),]
   public Int32 Id { get; set; }
   [Key, Column(Order = 2)]
   public int TenantId { get; set; }
   public string Name { get; set; }
}

public class Project
{
   [Key, Column(Order = 1),]
   public Int32 Id { get; set; }
   [Key, Column(Order = 2)]
   public int TenantId { get; set; }
   Public string Name { get; set; }
}

我也有这样的联接表ProjectPerson:

上面我已经定义了ProjectProjectPerson的关系.请注意,公共类ProjectPerson { [键,列(顺序= 1),] 公共Int32 ID {放; } [键,列(顺序= 2)] [ForeignKey("Project")] public int TenantId {get;放; }

Above I have defined a Project to ProjectPerson relationship. Note that public class ProjectPerson { [Key, Column(Order = 1),] public Int32 Id { get; set; } [Key, Column(Order = 2)] [ForeignKey("Project")] public int TenantId { get; set; }

   [ForeignKey("Project")]
   public int ProjectId { get; set; }

   public DateTime AddedDate{ get; set; }

   public virtual Project Project { get; set; }
}

TenantId用作主键和外键的一部分.

TenantId is used as a part of the primary and foreign key.

到目前为止,该模型可以按预期工作.但是PersonProjectPerson的关系丢失了.

Up to this point, the model works as expected. But the Person to ProjectPerson relationship is missing.

我在ProjectPerson

  [ForeignKey("Person")]
  public int PersonId { get; set; }

  public virtual Person Person { get; set; }

肯定没有映射到TenantId.我不知道该怎么定义

Definitely mapping to TenantId is missing. I don't know how to define it

更新

我发现了这个.但仍然不满意,因为还有其他TenantId(PersonTenantId)作为外键.

I found this. but still im not satisfied as there is additional TenantId ( PersonTenantId) as a foreign key.

 public class ProjectPerson
 {
   [Key, Column(Order = 1),]
   public Int32 Id { get; set; }
   [Key, Column(Order = 2)]
   [ForeignKey("Project")]
   public int TenantId { get; set; }

   [ForeignKey("Project")]
   public int ProjectId { get; set; }

   [ForeignKey("Person")]
   public int PersonId { get; set; }
   [ForeignKey("Person")]
   public int PersonTenantId { get; set; } // duplicate


   public DateTime AddedDate{ get; set; }

   public virtual Project Project { get; set; }
   public virtual Person Person { get; set; }

}

推荐答案

使用流畅的API对联结表中的两个FK重复使用TentantId列. ProjectId也应包含在联结表的PK中.请注意,我修改了组合主键列的顺序,以TenantId作为第一列.

Use the fluent API to reuse the TentantId column for both FK's in the junction table. ProjectId should also be included in the junction table's PK. Note that I modified the order of the composite primary key columns to have TenantId as the first column.

    public class Person
    {
        [Key, Column(Order = 0)]
        public int TenantId { get; set; }
        [Key, Column(Order = 1)]
        public int PersonId { get; set; }

        public string Name { get; set; }

        public virtual ICollection<ProjectPerson> ProjectPeople { get; set; }
    }

    public class Project
    {
        [Key, Column(Order = 0)]
        public int TenantId { get; set; }
        [Key, Column( Order = 1 )]
        public int ProjectId { get; set; }

        public string Name { get; set; }

        public virtual ICollection<ProjectPerson> ProjectPeople { get; set; }
    }

    public class ProjectPerson
    {
        [Key, Column( Order = 0 )]
        public int TentantId { get; set; }
        [Key, Column( Order = 1 )]
        public int ProjectId { get; set; }
        [Key, Column( Order = 2 )]
        public int PersonId { get; set; }

        public DateTime AddedDate { get; set; }

        public virtual Project Project { get; set; }
        public virtual Person Person { get; set; }
    }


    protected override void OnModelCreating( DbModelBuilder modelBuilder )
    {
        base.OnModelCreating( modelBuilder );

        modelBuilder.Entity<Project>()
            .HasMany(pr => pr.ProjectPeople )
            .WithRequired( pp => pp.Project )
            .HasForeignKey( pp => new { pp.TentantId, pp.ProjectId } );

        modelBuilder.Entity<Person>()
            .HasMany( pe => pe.ProjectPeople )
            .WithRequired( pp => pp.Person )
            .HasForeignKey( pp => new { pp.TentantId, pp.PersonId } );
    }

这篇关于EF同一主键上有多个外键关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-29 18:10