2011-12-05 33 views
7

Đang cập nhật một đối tượng với MVC3MVC3 với EF 4.1 và EntityState.Modified

Tôi có một mô hình mà tôi có thể sửa đổi, xin vui lòng xem mẫu dưới đây:

[HttpPost] 
public ActionResult Edit(Company c) 
{ 
     if (ModelState.IsValid) 
     { 
      db.Entry(c).State = EntityState.Modified; 
      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 
     return View(c); 
} 

Mô hình này có các lĩnh vực khác mà không phải là hiển thị trong chế độ xem và người dùng không thể sửa đổi, nhưng khi tôi nhấp vào nút gửi, các trường không hiển thị trong chế độ xem đã được đặt thành rỗng.

Tôi có thể bằng cách nào đó để EF biết không sửa đổi một số trường nhất định không? Cảm ơn.

Trả lời

12

Nói chung tốt hơn là không liên kết trực tiếp với đối tượng thực thể, thay vì tạo mô hình chỉnh sửa và liên kết với đối tượng đó.

Sau khi tất cả .. phải làm gì để ngăn ai đó đăng lại các giá trị bạn không muốn thay đổi bằng cách tiếp cận này?

Vấn đề chính ở đây là một thực tế rằng những thay đổi ràng buộc mô hình MVC các thuộc tính trong mô hình trước khi nó trong một bối cảnh do đó khuôn khổ thực thể không biết được giá trị đã thay đổi (và do đó cần được cập nhật)

Bạn đã giảm nhẹ điều đó một chút với db.Entry(c).State = EntityState.Modified; nhưng điều đó cho khung pháp nhân biết rằng toàn bộ bản ghi đã được cập nhật.

Tôi thường làm như sau:

  1. Bind to một mô hình đặc biệt cho điều khiển này đầu tiên
  2. Tạo một thể hiện của các lớp thực thể bạn muốn cập nhật, thiết lập Id cho phù hợp và gắn nó vào bối cảnh
  3. Cập nhật thuộc tính trên thực thể giống với mô hình bạn đã liên kết (đối tượng được đính kèm và do đó khung pháp nhân đang theo dõi cột nào đang được thay đổi ngay bây giờ)
  4. SaveChanges

Bước 3 là một chút tẻ nhạt do đó xem xét sử dụng một công cụ như automapper để làm cho mọi việc dễ dàng hơn

Edit:

[HttpPost] 
    public ActionResult Edit(Company c) 
    { 
     if (ModelState.IsValid) 
     { 
      Company dbCompayObjct = new Company { companyId = c.companyId }; 
      db.Company.Attach(dbCompayObjct); 

      dbCompanyObjct.CompanyName = c.CompanyName; 
      dbCompanyObjct.City = c.City; 

      db.SaveChanges(); 

      return RedirectToAction("Index"); 
     } 
     return View(c); 
    } 
+0

Xin chào, Cảm ơn bạn đã trả lời, tôi sửa đổi Hành động Chỉnh sửa thành mã bên dưới, bạn có thể vui lòng cho tôi biết nếu đây là ý của bạn. srry chỉ mới bắt đầu học tập và EF MVC [HttpPost] public ActionResult Chỉnh sửa (Công ty c) { if (ModelState.IsValid) { Công ty dbCompanyObjct = db.Company.Find (c.companyID); dbCompanyObjct.CompanyName = c.CompanyName; dbCompanyObjct.City = c.City; db.SaveChanges(); trả về RedirectToAction ("Chỉ mục"); } return View (c); } Ngoài ra, bạn có thể giải thích cho tôi automapper là gì không? Làm thế nào để tôi sử dụng nó? cảm ơn – Ben

+0

Tôi xin lỗi vì mã không được căn chỉnh, khó đọc, không có ý tưởng tại sao nó không được sắp xếp ... lời khuyên plz nếu mã đúng. – Ben

+0

Điều đó sẽ hiệu quả, tôi sẽ đăng một bản cập nhật nhanh chóng để cho thấy rằng bạn không cần tìm kiếm lần đầu tiên Tìm số –

3

Bạn đang ghi đè rõ ràng bản ghi hiện có của mình với bản ghi chưa hoàn chỉnh. Khi bạn sử dụng phương pháp trên, nó sẽ thay thế hoàn toàn phương thức hiện có.

Bạn cần phải điền vào tất cả các trường bạn không muốn thay thế bằng giá trị hiện có hoặc bạn cần lấy bản ghi hiện có và sửa đổi các trường bạn muốn sửa đổi, sau đó lưu.

+0

Không có cách nào để chỉ định trong lớp mô hình cho trường ví dụ "applicationDate" để không cho phép sửa đổi giá trị, tương tự như cách chúng ta không thể sửa đổi khóa chính của thực thể mô hình? – Ben

+2

@ user1042528 - bạn không hiểu. Bạn đang thay thế toàn bộ bản ghi, không cập nhật các trường riêng lẻ. Nó không quan trọng nếu bạn có thể ngăn chặn các lĩnh vực được ghi vào, vì bạn không thực sự viết trên chúng. Bạn đang thay thế toàn bộ bản ghi.Nó giống như sự khác biệt giữa thay thế một chai bia trong một gói sáu, và chỉ nhận được một gói 6 khác nhau mà chỉ có một chai trong đó. Bạn không thay thế 5 người khác không có gì, bạn đang thay thế toàn bộ hồ sơ. –

+0

Thx cho lời giải thích của bạn, đây có phải là cách bạn cập nhật các trường riêng lẻ không? [HttpPost] hành động công khaiPhiên bản sửa đổi (Công ty c) { nếu (ModelState.IsValid) { Công ty dbCompanyObjct = db.Company.Find (c.companyID); dbCompanyObjct.CompanyName = c.CompanyName; dbCompanyObjct.City = c.City; db.SaveChanges(); trả về RedirectToAction ("Chỉ mục"); } return View (c); } – Ben

0

Reflection không phải lúc nào cũng xấu xa, đôi khi nó là bạn của bạn:

public ActionResult Edit(Company c) 
{ 
    if (ModelState.IsValid) 
    { 
     Company UpdateC = db.Company.find(c.CompanyID);   
     foreach (var property in typeof(Company).GetProperties()) 
     { 
      var propval = property.GetValue(c); 
      if (propval != null) 
      { 
       property.SetValue(UpdateC, propval); 
      } 
     } 

     db.SaveChanges(); 
     return RedirectToAction("Index"); 
    } 
    return View(c); 
} 
Các vấn đề liên quan