我想使用代码优先方法使用EF 6创建多对多关系。我的实体使用复合主键(处理多租户)。
让我们采取简单而经典的例子。我有两个实体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
的关系。注意公共类ProjectPerson
{
[Key,Column(Order = 1),]
public Int32 Id {get;组; }
[Key,Column(Order = 2)]
[ForeignKey的("项目&#34)]
public int TenantId {get;组; }
[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; }
}
答案 0 :(得分:1)
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 } );
}