8

このエンティティがあり、entityframework を使用して更新したい

 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 にアタッチし、そのステータスを「変更済み」に更新すると、同じ問題が発生します。

AutoMapper の使用:

// 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 と共に正しく使用することは、間違いなく最も簡単な方法の 1 つです。

于 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 Employee set FirstName='modifiedValue', Email='modifiedValue' where Id=1138.

誰かがこれよりも良い答えを知っている場合は、提案を投稿してください

于 2013-02-01T13:46:33.907 に答える