2012-04-26 29 views
8

Sử dụng khung Entity Mã Trước tiên, tôi có cái gì đó như:Tại sao thiết lập EntityState để tách rời một thuộc tính của danh sách loại <T>?

public class Foo 
{ 
    public int Id { get; set; } 

    public List<Bar> Bars { get; set; } 
}  

Foo foo = (from f in ctx.Foos.Include("Bars") where f.Id == 42 select f).Single(); 

// At this point foo.Bars is populated 

ctx.Entry(foo).State = EntityState.Detached; 

// At this point foo.Bars is an empty List 

Tại sao tách một đối tượng gây ra đó là tài sản public List<string> Bars, được một cách rõ ràng và thành công bao gồm, được làm trống?

Quy trình chính xác để tách đối tượng có thể có nhiều thuộc tính là gì?

Trả lời

9

Lý do tại sao trong danh sách được làm trống là sự kết hợp của hai nguyên tắc trong Entity Framework:

  1. Khi bạn tách một đối tượng duy nhất đối tượng này tự nó được tách ra mà không có đối tượng bất kỳ thuộc tính định hướng tham khảo.

  2. ObjectContext/DbContext không cho phép giữ biểu đồ đối tượng được gắn một phần vào ngữ cảnh và được tách một phần. Mặc dù điều này có thể xảy ra như một trạng thái tạm thời khi sử dụng POCOs EF sẽ luôn luôn sửa trạng thái tạm thời này bằng cách tự động gắn các đối tượng tách rời trong biểu đồ bên trong các phương thức khác nhau (như Add, Attach, đặt trạng thái của thực thể, v.v.) hoặc mới nhất khi SaveChanges được gọi là.

Điều này có nghĩa là khi bạn tách đối tượng gốc ra khỏi ngữ cảnh, EF sẽ xóa danh sách trẻ em vì: a) trẻ em được đính kèm (quy tắc 1) và b) kết hợp các đối tượng tách rời và được đính kèm trong biểu đồ không được phép (quy tắc 2).

Theo như tôi có thể nói không có cách nào để tách biểu đồ đối tượng khỏi ngữ cảnh trong khi duy trì cấu trúc cây ban đầu. Bạn có thể tách cha mẹ và sau đó là con cái sau mỗi khác. Kết quả là bạn đã tách tất cả các đối tượng của cây khỏi ngữ cảnh nhưng cây bị phá hủy cùng một lúc - mỗi thuộc tính điều hướng bị vô hiệu hóa. Mục đích chính của việc tách các thực thể theo cách thủ công là giải phóng chúng để thu gom rác trong các tình huống mà bạn có giới hạn tài nguyên bộ nhớ và không muốn và cần giữ một lượng lớn các đối tượng trong ngữ cảnh. Với mục đích này, cấu trúc đồ thị bị phá hủy không quan trọng.

Tôi không biết tại sao bạn cần tách các đối tượng ra khỏi ngữ cảnh. Nhưng hãy nhớ rằng cũng có tùy chọn để tải các thực thể từ cơ sở dữ liệu mà không cần gắn chúng vào ngữ cảnh ngay từ đầu, như sử dụng AsNoTracking().

Một câu trả lời về vấn đề này với một số tài liệu tham khảo tài liệu MSDN là ở đây: https://stackoverflow.com/a/7693732/270591

+0

Các DbContext đi ra khỏi phạm vi rất lâu trước khi đối tượng của tôi là bao giờ xử lý. Sẽ tải đối tượng của tôi với 'AsNoTracking()' cho phép DbContext được thu thập, hay đối tượng của tôi vẫn duy trì một tham chiếu đến nó? Đó là mối quan tâm chính của tôi. –

+0

@EricJ .: Bạn đang sử dụng mã EF đầu tiên, do đó các thực thể của bạn là POCO. Nếu bạn không sử dụng tải chậm (và có vẻ bạn không vì 'Foo.Bars' không phải là' virtual') thì các thực thể không phải là proxy và chúng không có tham chiếu đến ngữ cảnh. Vì vậy, câu trả lời là có, ngữ cảnh sẽ được thu thập rác ngay cả khi bạn vẫn giữ một tham chiếu đến thực thể của bạn. – Slauma

+0

Nếu các thực thể là proxy, thì ngữ cảnh sẽ không được thu gom rác cho đến khi các thực thể được xử lý? –

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