EF导航属性更新

EF navigation property update

抱歉我的英语不好。

我有一些 class 和从 DB

生成的 EF 上下文

1.Question

public int Id { get; set; }
public string Content { get; set; }

public virtual ICollection<Answer> Answer { get; set; }

2.Answer

public int Id { get; set; }
public string Content { get; set; }
public bool IsTrue { get; set; }

public virtual Question Question { get; set; }

通过服务进行的所有 CRUD。这是问题

的更新方法
public void Update(Question q)
{
   var editQuestion = GetById(q.Id); //get entity by id
   editQuestion.Answer = null;
   _repository.Update(editQuestion);

    q.Answer.Each(answer => answer.Question=editQuestion);

    editQuestion.Answer = q.Answer;
    editQuestion.Content = q.Content;

   _repository.Update(editQuestion);
   _unitOfWork.Commit();
}

_repository.Update(T实体)=>

public virtual void Update(T entity)
{
   DbEntityEntry entityEntry = _context.Entry<T>(entity);
   entityEntry.State = EntityState.Modified;
}

现在在 Db 中不更新旧答案,而是添加新答案 (q.Answer)。在 q.Answer 中可能包含更新的旧答案和一些新答案。

如何更新问题?

更新:_unitOfWork.Commit()

public void Commit()
{
   _context.SaveChanges();
}

进入状态就不用玩了。只需通过其 Id 获取实体,修改相关属性,从上下文中删除旧答案,将新答案添加到集合中,调用 SaveChanges() 即可完成工作。

通常,人们会这样写:

public void Update(Question q)
{
  using(var context = new MyDbContext())
  {
    var entity = context.Question.Find(q.Id);
    entity.Content = q.Content;

    foreach(var oldAnswer in entity.Answer)
    { 
      context.Answers.Remove(oldAnswer);
    }

    entity.Answer.Clear(); 

    foreach(var newAnswer in q.Answer)
    {
      entity.Answer.Add(newAnswer);
    }

    context.SaveChanges();
  } 
}

如果您没有使用 using 模式,请不要忘记通过调用 context.Dispose() 在最后处理上下文。

请注意,这是一个解决方案,其中答案记录将从数据库中删除并重新创建,即使它们没有更改。

或者,您可以编写一个解决方案,在其中更新现有记录,只删除不再存在的答案:

public void Update(Question q)
{
  using(var context = new MyDbContext())
  {
    var entity = context.Question.Find(q.Id);
    entity.Content = q.Content;

    foreach(var newAnswer in q.Answer)
    {
      if (entity.Answer.All(a => a.Id != newAnswer.Id)
      {
        entity.Answer.Add(newAnswer);
      }
    }

    foreach(var oldAnswer in entity.Answer)
    { 
      if (q.Answer.All(a => a.Id != oldAnswer.Id)
      {
        context.Answers.Remove(oldAnswer);
      }
      else
      {
        var newAnswer = q.Answer.Single(a => a.Id == oldAnswer.Id);
        oldAnswer.Content = newAnswer.Content;
        oldAnswer.IsTrue = newAnswer.IsTrue;
      }
    }

    context.SaveChanges();
  } 
}