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 的正确方法?

EF Core:LINQ 选择“多对多”到“多对多”

Set a Many-to-Many Relationship设置多对多关系 (EF)

Set a One-to-Many Relationship设置一对多关系 (EF)

Entity Framework Many to Many Relation Mapping(Entity Framework多对多关系映射)

多对多 EF Core 已被跟踪 - C# Discord Bot