2

我有2个模型类。更新多对多关系

public class Candidate 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public ICollection<Skill> Skills { get; set; } 
} 

public class Skill 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public ICollection<Candidate> Candidates { get; set; } 
} 

这为我创建了3个表格。

  • 考生
    • ID名称
    • 1汤姆
    • 约翰二

  • 技能
    • ID名称
    • 1 C#
    • 2 MVC
    • 3 SQL
    • 4 NHibernate的
    • 5的Java

我做了在自动生成的表的关联:

  • CandidateSkills
    • CandidateId SkillId

现在我想更新技能candidateId 1即汤姆谁愿意删除他的SkillId:2即MVC并添加新的SkillId:4 & 5即nHibernate & Java分别为

我得到的集IDS从形式即3,4 和候选I​​D:1,由于2被用户移除。

我的API是这样的:

public Candidate Add(int candidateId, int[] skillIds) 
{ 
    var model = dbContext.candidate.Find(candidateId); 
} 

如何以有效的方式更新候选纪录,成为最小的数据库调用?

回答

4

随着实体框架许多-to-many关联,你只能使用对象,而不是与原始的ID值。

public void Add(int candidateId, int[] skillIds) 
{ 
    var model = dbContext.candidate.Include(c => c.Skills) 
         .Single(candidateId => c.candidateId == candidateId); 

    var skills = dbContext.Skills.Where(s => skillIds.Contains(s.Id)).ToArray(); 
    foreach (var skill in skills) 
    { 
     model.Skills.Add(skill); 
    } 

    dbContext.SaveChanges(); 
} 

您必须获取候选人的技能加载,因此Include。必须为EF加载技能才能够跟踪对收集的更改。

如果你真的对优化性能有很大的帮助,你必须在你的模型中创建一个类结点类CandidateSkill,这样你就可以在不加载候选或技能对象的情况下添加/删除关联。

+0

谢谢@GertArnold –

+0

或者使用[存根实体](http://stackoverflow.com/a/16787524/861716)。 –

0

您可以将实体状态标记为已修改并保存上下文。

public void UpdateCandidate(Candidate candidate) 
{ 
    Context.Entry(candidate).State = EntityState.Modified; 
} 
2
public class CandidateToSkill 
{ 
    public Candidate Candidate{ get; set; } 
    [Key,Column(Order = 0)] 
    public int CandidateID { get; set; } 


    [Key,Column(Order = 1)] 
    public int SkillID{ get; set; } 

    public Skill Skill { get; set; } 


} 

您也需要添加这个类作为DbSet在你的DbContext类

public class Candidate 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public ICollection<CandidateToSkill> CandidateSkills{ get; set; } 
} 

public class Skill 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public ICollection<CandidateToSkill> SkillCandidates{ get; set; } 
} 

与此示例中的控制器代码

public void Add(int candidateId, int[] skillIds) 
{ 
    using (var db = new YourdbContext()) 
     { 
      foreach (int skillID in skillIds) 
      { 
       db.CandidateToSkill.Add(new CandidateToSkill(){skillID,candidateId}); 
      } 
      db.SaveChanges(); 
     } 

} 

u必须只有标志着候选人添加到我们的上下文(在你的链接表)和添加EM到DB与db.SaveChanges()