public HttpResponseMessage Put(Employee employee) { if (ModelState.IsValid) { employee.Company = db.Company.Find(employee.Company.CompanyId); // ... 更多的關聯表 db.Entry(employee).State = EntityState.Modified; try { db.SaveChanges(); } catch (DbUpdateConcurrencyException ex) { return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex); } } else { return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState); } return Request.CreateResponse(HttpStatusCode.OK); }
因為在頁面上是使用 Extjs,所以在資料傳送過來時,關聯的資料只會有 Key 值,必需再去與資料庫要被關聯的完整資料,要不然資料將會被自動新增,會多了筆垃圾資料,多做幾次就會有幾筆,所以必須得在與資料庫要一次。
此時問題來了,在我將頁面上資料送到 Put 時,發現 Employee 中的資料可以被更新,但是 Employee 關聯的表的 ID 沒有被更新。
什麼???!! 這是什麼情況。
參考了許多資料:EntityState 列舉型別、ObjectStateEntry 類別、EDM的一些常见处理数据操作、MVC3+EF4.1学习系列(二)-------基础的增删改查和持久对象的生命周期变化、Entity Framework 4.1 Code First学习之路(二)、EntityFrameworkAdd方法与Attach区别
後來我觀察了一下,在 Put 一進來時 db.Entry(employee).State 為 Detached ( 意思是不在 Context 裡,沒有被追蹤 ),接著我將程式碼改為:
// 將狀態改為 Unchanged,也就是將它附加到 Context 內 db.Employee.Attach(employee); // 將狀態改為 Modified db.Entry(employee).State = EntityState.Modified;
結果還是一樣.....這我就看不懂了,找了許多範例都是這樣,都沒有看到資料在 Put 進來之後,還有做修改的。但後來看到一篇文章 Working With Entity Framework Detached Objects,
先搜尋出該筆資料塞進另一個實體,再將此實體加入關聯的表的資料,接著使用 Entry
程式碼如下:
public HttpResponseMessage Put(Employee employee) { if (ModelState.IsValid) { Employee _employee = db.Employee.Find(employee.EmployeeId, employee.EffectiveDate); _employee.Company = db.Company.Find(employee.Company.CompanyId); // ... 更多關聯表 db.Entry(_employee).CurrentValues.SetValues(employee); try { db.SaveChanges(); } catch (DbUpdateConcurrencyException ex) { return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex); } } else { return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState); } return Request.CreateResponse(HttpStatusCode.OK); }
程式碼改為這樣就可以更新了,重新建立一個實體去找出資料庫最新的資料 ( 狀態為 Unchanged ),再將所有修改過的值原封不動的設定到實體上 ( 狀態為 Modified ),最後在送到資料庫去更新,這樣就解決問題了。
沒有留言 :
張貼留言