同一主键上的 EF 多个外键关系

EF multiple foreign key relationship on same primary key

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

让我们举一个简单的 class 例子。我有两个实体 ProjectPerson,它们具有多对多关系:

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

我也有这样的加入tableProjectPerson

上面我定义了一个 ProjectProjectPerson 的关系。请注意 public class ProjectPerson { [键,列(订单 = 1),] public Int32 Id { 得到;放; } [键,列(顺序 = 2)] [外键("Project")] public int TenantId { 得到;放; }

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

   public DateTime AddedDate{ get; set; }

   public virtual Project Project { get; set; }
}

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

到目前为止,该模型按预期运行。但是缺少 PersonProjectPerson 的关系。

我在 ProjectPerson class

中添加了以下两行
  [ForeignKey("Person")]
  public int PersonId { get; set; }

  public virtual Person Person { get; set; }

确实缺少到 TenantId 的映射。不知道怎么定义

更新

我找到了这个。但我仍然不满意,因为有额外的 TenantId ( PersonTenantId) 作为外键。

 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 为联结 table 中的两个 FK 重用 TentantId 列。 ProjectId 也应该包含在路口 table 的 PK 中。请注意,我修改了复合主键列的顺序,将 TenantId 作为第一列。

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