Ef core many 2 many mapping
Posted
技术标签:
【中文标题】Ef core many 2 many mapping【英文标题】: 【发布时间】:2022-01-11 00:11:24 【问题描述】:我有一个像这样的 3 方式多对多关系:
table 1 skill
table 2 instructions
table 3 person
现在我需要一种方法来为技能和人员的组合设置指令列表。我正在考虑拥有 1 个具有此映射 SkillId、InstructionId 和 PersonId 的表。我尝试使用 HasOne.Withmany.HasForeignKey 进行设置,但它不起作用。我收到一个错误
属性或导航“Instruction”无法添加到实体类型“PersonSkillInstruction”,因为实体类型“PersonSkillInstruction”上已存在同名的属性或导航
如果我只设置主键并让 .netcore 5.0 为我解决问题,我会遇到另一个错误
“PersonSkillInstruction.Instruction”属性属于“InstructionEntity”类型,当前数据库提供程序不支持。更改属性 CLR 类型,或使用“[NotMapped]”属性或使用“OnModelCreating”中的“EntityTypeBuilder.Ignore”忽略该属性
我知道我可以为人员和技能创建多对多并设置一个 ID,然后将其与指令结合使用,但感觉很可疑。
我怎样才能使这 3 路多对多工作?
我正在使用 .netcore 5.0、ef core、code first 和 sqlserver
【问题讨论】:
【参考方案1】:我认为正确的做法是你所说的:
我知道我可以做一些事情,比如为人和创建多对多 技能并设置一个ID,然后将其与指令结合使用
不过,如果您想创建 PersonSkillInstruction 表,这里有一个示例。
public class PersonSkillInstruction
[ForeignKey("person")]
public int PersonId get; set;
[ForeignKey("skill")]
public int SkillId get; set;
[ForeignKey("instructions")]
public int InstructionId get; set;
public virtual Person Person get; set;
public virtual Skill Skill get; set;
public virtual Instruction Instruction get; set;
那么你需要在DBContext中设置PK如下:
protected override void OnModelCreating(ModelBuilder modelBuilder)
// ...
modelBuilder.Entity<PersonSkillInstruction>()
.HasKey(t => new t.PersonId, t.SkillId, t.InstructionId );
// ...
添加新迁移后,您必须引用两个类似这样的操作以避免循环:
// ...
onDelete: ReferentialAction.Restrict
// ...
如果此表将有大量查询,我建议使用具有唯一索引的代理键,如下所示:
modelBuilder.Entity<PersonSkillInstruction>()
.HasIndex(t => new t.PersonId, t.SkillId, t.InstructionId )
.IsUnique();
Link about surrogate key
【讨论】:
以上是关于Ef core many 2 many mapping的主要内容,如果未能解决你的问题,请参考以下文章
在 EF Core6 中使用 Many2Many 的正确方法?
Set a Many-to-Many Relationship设置多对多关系 (EF)
Set a One-to-Many Relationship设置一对多关系 (EF)
Entity Framework Many to Many Relation Mapping(Entity Framework多对多关系映射)