我想使用代码优先方法使用 EF 6 创建多对多关系。我的实体使用复合主键(以处理 Multi-Tenancy )。
让我们举一个简单而经典的例子。我有两个实体 Project
和 Person
,它们具有多对多关系:
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
关系。请注意公共(public)类 ProjectPerson
{
[键,列(顺序 = 1),]
公共(public) Int32 Id { 获取;放; }
[键、列(顺序 = 2)]
[ForeignKey(“项目”)]
公共(public) int TenantId { 获取;放; }
[ForeignKey("Project")]
public int ProjectId { get; set; }
public DateTime AddedDate{ get; set; }
public virtual Project Project { get; set; }
}
TenantId
用作主键和外键的一部分。
到目前为止,模型按预期工作。但缺少 Person
到 ProjectPerson
关系。
我已将以下两行添加到 ProjectPerson
类
[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; }
}
最佳答案
使用 Fluent API 为联结表中的两个 FK 重用 TentantId
列。 ProjectId
还应包含在联结表的 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 } );
}
关于c# - EF 同一主键上的多个外键关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30075433/