2011-12-08 38 views
8

Tôi có một dự án MVC và sử dụng Entity Framework Code First và các đối tượng POCO cho cơ sở dữ liệu. Ví dụ:Làm thế nào để cập nhật các thực thể liên quan trong Entity Framework

public class ClassA 
{ 
    public int? Id {get; set;} 
    public string Name { get; set;} 
    public virtual ClassB B {get; set;} 
} 

public class ClassB 
{ 
    public int? Id {get;set;} 
    public string Description {get;set;} 
} 

Tôi có ActionResult để tạo hoặc chỉnh sửa mô hình. Vấn đề là khi tôi gọi ActionResult này để cập nhật mô hình, và model.B đã được thay đổi, mối quan hệ không được lưu trong cơ sở dữ liệu. Khi ActionResult được gọi để tạo một đối tượng mới, nó hoạt động như mong đợi. Tôi giải quyết điều này như thế nào?

public ActionResult Save(ClassA model) 
{ 
    model.B = GetBFromDb(model.B.Id.Value); 

    if(ModelState.IsValid) 
    { 
    if (id.HasValue) 
    { 
     context.Entry(model).State = System.Data.EntityState.Modified; 
    } 
    else 
    { 
     context.ClassAs.Add(model); 
    } 
    context.SaveChanges(); 
    // redirect to index etc. 
    } 
    return View("EditForm", model); 
} 

Trả lời

3

Tôi giải quyết nó bằng cách thay đổi ClassA với một chìa khóa nước ngoài ClassB, và đặt giá trị của BId:

public class ClassA 
{ 
    public int? Id {get; set;} 
    public string Name { get; set;} 
    public int BId {get;set;} // foreign key to B 
    public virtual ClassB B {get; set;} 
} 

Tại sao thuộc tính khóa ngoài này thực hiện công việc thay vì ky ngoài EF được tạo ra?

+3

khi bị ngắt kết nối, khi bạn không có khóa ngoài có một số những khoảng trống mà EF không thể làm việc xung quanh và bạn phải chứng minh thêm mã. Nếu không, nó không thể thấy mối quan hệ. Với tài sản FK, nó là một giá trị vô hướng và dễ dàng hơn cho EF để theo dõi các quy trình. Tôi thực sự đã viết cột Điểm dữ liệu tháng 1 năm 2012 của mình về chủ đề chính xác này! EF dễ sử dụng hơn nhiều khi bạn có tài sản vô hướng FK. Nếu không nhiều chức năng bạn mong đợi "chỉ làm việc" không thể & itf buộc bạn phải hiểu rõ hơn về những gì đang diễn ra và cách cung cấp thông tin cần thiết. Rất tiếc, tôi không thấy FK bị thiếu trước –

+0

@JulieLerman, không sao cả, cảm ơn sự giúp đỡ của bạn! :) – Marthijn

2

Bạn không thể chỉ cần gọi:

context.Entry(model).State = System.Data.EntityState.Modified; 

Thực thể này phải được lấy ra từ bối cảnh đầu tiên để EF có thể bắt đầu theo dõi nó. Sau đó, bạn sẽ muốn áp dụng bất kỳ thay đổi nào cho thực thể đó trước khi gọi context.SaveChanges().

var entity = context.ClassAs.Find(model.Id); 

// set properties you want to modify on entity 
entity.Name = model.Name; 
entity.ClassB = context.ClassBs.Find(model.ClassB.Id); 
// other changes to entity as required... 

context.SaveChanges(); 

Bằng cách này EF theo dõi entity và biết cách áp dụng bản cập nhật chống lại nó.

+0

Cảm ơn công trình này! Và làm thế nào để tôi đặt 'entity.ClassB = null;'? Có vẻ như thiết lập nó là null không hoạt động. – Marthijn

+1

Yuck ... context.Entry (model) .State sẽ gây ra bối cảnh để xem nếu mô hình đang được theo dõi và nếu không, nó sẽ bắt đầu theo dõi nó. Bạn không phải thực hiện một truy vấn db khác để có được cá thể mô hình được theo dõi. Vấn đề Henkie đang gặp phải với ocde đó là Entry rằng phương thức đó sẽ chỉ thay đổi thiết lập trạng thái của thực thể được truyền vào. Cài đặt trạng thái "đã sửa đổi" sẽ không được áp dụng cho phần còn lại của đồ thị. –

+0

@JulieLerman Cảm ơn tôi đã tìm thấy một số hướng dẫn cũng đặt trạng thái để sửa đổi. Nhưng sau đó tôi vẫn có vấn đề quan hệ của tôi sẽ không cập nhật. – Marthijn

0

Nếu bạn đính kèm và sau đó đặt trạng thái thành khung thực thể được sửa đổi sẽ gửi tất cả các thuộc tính để cập nhật. Bạn không cần phải thực hiện phương pháp rái cá ở đây dưới đây vì điều đó làm cho toàn bộ tải riêng biệt xảy ra. Nếu bạn làm điều đó theo cách đó không có ý nghĩa trong đi qua trong một mô hình, chỉ có một id và sau đó bạn gọi TryUpdateModel để điền vào các thuộc tính từ biểu mẫu.

Cá nhân các đính kèm như sửa đổi ở đây là một chút bụi vì nó không đòi hỏi một chuyến đi vòng hoàn chỉnh do chế độ nạp dữ liệu

http://geekswithblogs.net/michelotti/archive/2009/11/27/attaching-modified-entities-in-ef-4.aspx

Các vấn đề liên quan