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()