Ef 核心多 2 多映射

Ef core many 2 many mapping

我有一个像这样的 3 路多对多关系:

table 1 skill
table 2 instructions
table 3 person

现在我需要一种方法来为技能和人员的组合设置一个指令列表。我正在考虑让 1 table 具有此映射 SkillId、InstructionId 和 PersonId。我试图用 HasOne.Withmany.HasForeignKey 设置它,但它不起作用。我收到一个错误

The property or navigation 'Instruction' cannot be added to the entity type 'PersonSkillInstruction' because a property or navigation with the same name already exists on entity type 'PersonSkillInstruction'

如果我只设置主键并让 .netcore 5.0 为我做这件事,我会收到另一个错误

The property 'PersonSkillInstruction.Instruction' is of type 'InstructionEntity' which is not supported by the current database provider. Either change the property CLR type, or ignore the property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'

我知道我可以做一些事情,比如为 person 和 skill 创建多对多并设置一个 id,然后结合指令使用它,但感觉很可疑。

我怎样才能使这 3 种方法多对多工作?

我正在使用 .netcore 5.0、ef core、code first 和 sqlserver

我认为正确的做法是你说的:

I know I could do something like create a many to many for person and skill and set an id then use that in a combination with instruction

尽管如此,如果您想创建 PersonSkillInstruction table。

,这里有一个示例
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
// ...

如果这个 table 会有大量查询,我建议使用具有唯一索引的代理键,如下所示:

modelBuilder.Entity<PersonSkillInstruction>()
  .HasIndex(t => new { t.PersonId, t.SkillId, t.InstructionId })
  .IsUnique(); 

Link about surrogate key