8

我有这个实体,想使用实体框架更新

 EmployeeModel employee = new EmployeeModel
    {
        Id = 1000, //This one must 
        FirstName = modifiedValue,
        Email = modifiedValue, 
        LastName = originalValue,
        Phone = originalValue
    };

要更新的代码

_db.ObjectStateManager.ChangeObjectState(employee, EntityState.Modified);  
_db.SaveChanges();

这是更新后的 SQL 语句

Update Employee set Id=1138,FirstName='modifiedValue',Email='modifiedValue',LastName= 'OriginalValue',phone='originalValue' where Id=1138

但我期待这个

Update Employee set FirstName='modifiedValue', Email='modifiedValue' where Id=1138.

我不知道我在这里缺少什么。请告诉我。

4

3 回答 3

13

这个问题在处理 DTO 时很常见。从数据库中获取员工实体,映射到 DTO 并通过网络发送。客户端然后修改此 DTO 并将其发送回服务器。

当您触摸(设置)EF 实体上的属性时,EF 将假定该值已更改。即使旧值和新值完全相同。当您将 DTO 映射到实体并将其附加到 EF 并将其状态更新为“已修改”时,也会出现同样的问题。

使用自动映射器:

// This will result in the full update statement
var employee = AutoMapper.Mapper.Map<EmployeeDto, Employee>(dto);

// This will result in a smaller update statement (only actual changes)
var employee = dbContext.Employees.Find(dto.Id);
AutoMapper.Mapper.Map(dto, employee);

或者,手动(我会避免这样做,但只是为了完整起见):

// This will result in a smaller update statement (only actual changes)
var employee = dbContext.Employees.Find(dto.Id);
if (employee.Email != dto.Email )
    employee.Email = dto.Email;

可能还有其他一些方法可以解决这个问题......但是正确使用 AutoMapper 和 Entity Framework 绝对是最简单的方法之一。

于 2014-04-16T10:38:10.047 回答
6

这是我得到的解决方案

 var entity = _db.CreateObjectSet<Employee>();
 entity.Detach(employee);
 entity.Attach(employee);

 foreach (string modifiedPro in employeeModel.ModifiedProperties){
  _db.ObjectStateManager.GetObjectStateEntry(employee).SetModifiedProperty(modifiedPro);}

  _db.SaveChanges();

只修改了 sql update 语句中的值

Update Employee set FirstName='modifiedValue', Email='modifiedValue' where Id=1138.

如果有人知道比这更好的答案,请发表您的建议

于 2013-02-01T13:46:33.907 回答
0

你可以试试这个方法

public update(Person model)
{
    // Here model is model return from form on post
    var oldobj = db.Person.where(x=>x.ID = model.ID).SingleOrDefault();

    var UpdatedObj = (Person) Entity.CheckUpdateObject(oldobj, model);

    db.Entry(oldobj).CurrentValues.SetValues(UpdatedObj);
}

public static object CheckUpdateObject(object originalObj, object updateObj)
{
   foreach (var property in updateObj.GetType().GetProperties())
   {
      if (property.GetValue(updateObj, null) == null)
      {
         property.SetValue(updateObj,originalObj.GetType().GetProperty(property.Name)
         .GetValue(originalObj, null));
      }
   }
   return updateObj;
}
于 2018-08-31T06:06:08.193 回答