同一主键上的 EF 多个外键关系
EF multiple foreign key relationship on same primary key
我想使用代码优先的方法使用 EF 6 创建多对多关系。我的实体使用复合主键(以处理多租户)。
让我们举一个简单的 class 例子。我有两个实体 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; }
}
我也有这样的加入tableProjectPerson
:
上面我定义了一个 Project
到 ProjectPerson
的关系。请注意 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
用作主键和外键的一部分。
到目前为止,该模型按预期运行。但是缺少 Person
到 ProjectPerson
的关系。
我在 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 } );
}
我想使用代码优先的方法使用 EF 6 创建多对多关系。我的实体使用复合主键(以处理多租户)。
让我们举一个简单的 class 例子。我有两个实体 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; }
}
我也有这样的加入tableProjectPerson
:
上面我定义了一个 Project
到 ProjectPerson
的关系。请注意 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
用作主键和外键的一部分。
到目前为止,该模型按预期运行。但是缺少 Person
到 ProjectPerson
的关系。
我在 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 } );
}