问题描述
我想使用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).
让我们举一个简单而经典的例子.我有两个实体Project
和Person
具有多对多关系:
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
:
上面我已经定义了Project
到ProjectPerson
的关系.请注意,公共类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.
到目前为止,该模型可以按预期工作.但是Person
到ProjectPerson
的关系丢失了.
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同一主键上有多个外键关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!