在ef中更新实体

时间:2014-11-08 22:12:45

标签: entity-framework

好的,所以我有这个代码来决定数据库中是否存在一个项目:

 foreach (var result in model.Results)
            {

                if (_ef.Results.Any(o=>o.Dog.DogId==result.Dog.DogId))
                {
                    result.Event = _ef.SingleEvent(result.Event.EventId);
                    result.Dog = _ef.SingleDog(result.Dog.DogId);
                    _ef.UpdateResult(result);
                }
                else
                {
                    result.Event = _ef.SingleEvent(result.Event.EventId);
                    result.Dog = _ef.SingleDog(result.Dog.DogId);
                    _ef.SaveResult(result);   

                }

            }

现在,如果该项目不存在,我有:

public void SaveResult(Result newResult)
        {
            _context.Results.Add(newResult);
            _context.SaveChanges();
        }

如果它存在,我想更新它:

 public void UpdateResult(Result result)
        {
           //Must be missing something here
          _context.SaveChanges();
        }

我错过了一些明显的东西吗?感谢

2 个答案:

答案 0 :(得分:1)

您需要在致电SaveChanges之前更改对象状态:

public void UpdateResult(Result result) {
    // The missing something:  
   _context.Entry(result).State = EntityState.Modified;
   _context.SaveChanges();
}

另一种方式是致电:

_context.Attach(result);

在您开始修改对象之前。在这种情况下,您只需要在之后致电Save Changes并完成您的工作。

答案 1 :(得分:1)

在我看来,处理这样的更新的最可靠方法是从数据存储中获取现有实体,然后将更新数据映射到它。换句话说, UpdateResult 方法中的结果参数对象永远不会实际进入数据库,只会进入数据库。像这样:

public void UpdateResult(Result result)
{
    var existing = _context.Results.FirstOrDefault(x => x.Dog.DogId.Equals(result.Dog.DogId));
    if (existing == null)
        throw new Exception("Result to update not found");

    existing.Name = result.Name;
    .... map other relevant properties here...

    _context.SaveChanges();
}

在某些情况下,我会使用某种自动映射,这取决于在更新期间是否需要应用业务规则。我更喜欢使用AutoMapper进行自动映射。