2014-12-11 13 views
20

Tôi đang chạy một số mã điều chỉnh chạy trên một chồng lớn các thực thể, vì nó tiến trình giảm tốc độ, đó là vì số lượng thực thể được theo dõi trong ngữ cảnh tăng theo mỗi lần lặp lại, Có thể mất nhiều thời gian để tôi lưu các thay đổi vào cuối mỗi lần lặp lại. Mỗi lần lặp lại là độc lập và không thay đổi các thực thể được nạp trước tiên.Làm cách nào để xóa các thực thể được theo dõi trong khung thực thể

Tôi biết tôi có thể tắt theo dõi thay đổi nhưng tôi không muốn, bởi vì nó không phải là mã chèn số lượng lớn, nhưng tải các thực thể và tính toán một vài điều và nếu các con số không chính xác đặt số mới và cập nhật/xóa/tạo một số thực thể bổ sung. Tôi biết tôi có thể tạo một DbContext mới cho mỗi lần lặp và có lẽ điều đó sẽ chạy nhanh hơn làm tất cả trong cùng một trường hợp, nhưng tôi nghĩ rằng có thể có một cách tốt hơn.

Vì vậy, câu hỏi là; Có cách nào để xóa các thực thể được tải trước trong ngữ cảnh db không?

+0

bạn chỉ có thể gọi 'context.Entry (thực thể) .State = EntityState.Detached' và nó sẽ dừng lại theo dõi ing thực thể cụ thể đó. –

+0

Tại sao bạn không tạo ra một bối cảnh mới? Có thực sự không có chi phí lớn trừ khi bạn cần mã rất tối ưu. –

+0

khung thực thể truy cập máy chủ cơ sở dữ liệu chỉ cho các thực thể đã thay đổi, bạn không có mối quan tâm về hiệu suất về điều đó. nhưng bạn có thể tạo một ngữ cảnh mới chỉ bao gồm các bảng bạn làm việc để làm cho nó nhanh hơn. –

Trả lời

29

Bạn có thể thêm một phương pháp để bạn DbContext hoặc một phương pháp khuyến nông có sử dụng các ChangeTracker tách tất cả các gia tăng, thay đổi, và các tổ chức Deleted:

public void DetachAllEntities() 
{ 
    var changedEntriesCopy = this.ChangeTracker.Entries() 
     .Where(e => e.State == EntityState.Added || 
        e.State == EntityState.Modified || 
        e.State == EntityState.Deleted) 
     .ToList(); 
    foreach (var entity in changedEntriesCopy) 
    { 
     this.Entry(entity.Entity).State = EntityState.Detached; 
    } 
} 
+0

Đảm bảo gọi 'ToList' sau 'Where'. Nếu không, nó ném một System.InvalidOperationException: 'Bộ sưu tập đã được sửa đổi; hoạt động điều tra có thể không thực thi. ' – mabead

+0

@mabead thú vị ... có thể điều đó xảy ra trong các phiên bản mới hơn của EF. Tôi đã cập nhật câu trả lời để bao gồm đề xuất của bạn bởi vì nó có vẻ như là một điều tốt để làm chỉ trong trường hợp. Cảm ơn! –

+1

Trong thử nghiệm đơn vị của tôi, trạng thái mục nhập là "Chưa sửa đổi", maybse vì tôi sử dụng một giao dịch mà tôi quay trở lại vào cuối phương pháp thử nghiệm.Điều này có nghĩa rằng tôi đã phải thiết lập các mục theo dõi nhà nước để "tách" mà không kiểm tra trạng thái hiện tại, để kiểm tra của tôi chạy tất cả một cách chính xác cùng một lúc. Tôi gọi mã ở trên ngay sau khi quay lại giao dịch, nhưng tôi đã nhận nó, quay trở lại chắc chắn có nghĩa là trạng thái Unmodified. –

6

1. Khả năng: tách các mục nhập

dbContext.Entry(entity).State = EntityState.Detached; 

Khi bạn tách các mục theo dõi sự thay đổi sẽ ngừng theo dõi nó (và nên dẫn đến hiệu suất tốt hơn)

Xem: http://msdn.microsoft.com/de-de/library/system.data.entitystate(v=vs.110).aspx

2. Khả năng: hoạt động với trường Status riêng của bạn + bối cảnh bị ngắt kết nối

Có thể bạn muốn kiểm soát trạng thái của thực thể độc lập để có thể sử dụng biểu đồ bị ngắt kết nối. Thêm một tài sản cho tình trạng tổ chức và biến đổi tình trạng này vào dbContext.Entry(entity).State khi thực hiện các hoạt động (sử dụng một kho lưu trữ để làm điều này)

public class Foo 
{ 
    public EntityStatus EntityStatus { get; set; } 
} 

public enum EntityStatus 
{ 
    Unmodified, 
    Modified, 
    Added 
} 

Xem liên kết sau đây cho một ví dụ: https://www.safaribooksonline.com/library/view/programming-entity-framework/9781449331825/ch04s06.html

+0

Tôi nghĩ rằng việc thêm một phương thức mở rộng và chạy trên tất cả các thực thể trong ChangeTracker và việc tách chúng sẽ hoạt động. – hazimdikenli

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