Trong ứng dụng kinh doanh đa cấp của chúng tôi, chúng tôi có ObservableCollections
Các thực thể tự theo dõi được trả về từ các cuộc gọi dịch vụ. Ý tưởng là chúng tôi muốn có thể nhận các thực thể, thêm, cập nhật và xóa chúng từ phía máy khách thu thập, sau đó gửi các thay đổi này đến phía máy chủ, nơi chúng sẽ được lưu giữ lâu dài vào cơ sở dữ liệu.Làm thế nào để theo dõi các đối tượng bị xóa khỏi một ObservableCollection trong các kịch bản CRUD?
Thực thể tự theo dõi, như tên của chúng có thể đề xuất, tự theo dõi trạng thái của chúng. Khi một STE mới được tạo, nó có trạng thái Đã thêm, khi bạn sửa đổi thuộc tính, nó đặt trạng thái Đã sửa đổi, nó cũng có thể có Trạng thái đã xóa nhưng trạng thái này không được thiết lập khi thực thể bị xóa khỏi ObservableCollection
(hiển nhiên). Nếu bạn muốn hành vi này, bạn cần tự viết mã. Trong thực hiện hiện tại của tôi, khi một thực thể bị xóa khỏi ObservableCollection
, tôi giữ nó trong bộ sưu tập bóng, để khi ObservableCollection
được gửi trở lại máy chủ, tôi có thể gửi các mục đã xóa cùng, do đó, Entity Framework biết để xóa chúng.
cái gì đó dọc theo dòng:
protected IDictionary<int, IList> DeletedCollections = new Dictionary<int, IList>();
protected void SubscribeDeletionHandler<TEntity>(ObservableCollection<TEntity> collection)
{
var deletedEntities = new List<TEntity>();
DeletedCollections[collection.GetHashCode()] = deletedEntities;
collection.CollectionChanged += (o, a) =>
{
if (a.OldItems != null)
{
deletedEntities.AddRange(a.OldItems.Cast<TEntity>());
}
};
}
Bây giờ nếu người dùng quyết định để lưu các thay đổi của mình đến máy chủ, tôi có thể nhận được danh sách các mục đã xóa, và gửi chúng cùng:
ObservableCollection<Customer> customers = MyServiceProxy.GetCustomers();
customers.RemoveAt(0);
MyServiceProxy.UpdateCustomers(customers);
Tại thời điểm này, phương thức UpdateCustomers
sẽ xác minh bộ sưu tập bóng của tôi nếu có bất kỳ mục nào bị xóa và gửi chúng đến phía máy chủ.
Cách tiếp cận này hoạt động tốt, cho đến khi bạn bắt đầu nghĩ về vòng đời của các bộ sưu tập bóng tối này. Về cơ bản, khi ObservableCollection
là rác được thu thập, không có cách nào để biết rằng chúng ta cần xóa bộ sưu tập bóng khỏi từ điển của mình.
Tôi đã đưa ra một số giải pháp phức tạp về cơ bản quản lý bộ nhớ thủ công trong trường hợp này. Tôi giữ một WeakReference
đến ObservableCollection
và cứ sau vài giây tôi kiểm tra xem tham chiếu có không hoạt động hay không, trong trường hợp này tôi xóa bộ sưu tập bóng.
Nhưng điều này có vẻ như một giải pháp khủng khiếp ... Tôi hy vọng thiên tài tập thể của StackOverflow có thể làm sáng tỏ một giải pháp tốt hơn.
EDIT:
Cuối cùng tôi quyết định đi với subclassing ObservableCollection
. Mã proxy dịch vụ được tạo ra vì vậy nó là một nhiệm vụ tương đối đơn giản để thay đổi nó để trả về kiểu dẫn xuất của tôi.
Cảm ơn tất cả trợ giúp!
Tại sao không giữ tham chiếu yếu cho chính các thực thể đó, chứ không phải là bộ sưu tập? Sau đó, bạn không cần phải fiddle với bộ sưu tập như là các thực thể được gỡ bỏ; chỉ cần đảm bảo các tham chiếu được hiển thị khi bạn lặp lại. –
Giữ tài liệu tham khảo yếu cho các thực thể, thay vì thêm chúng vào bộ sưu tập bóng, sẽ cho phép chúng được thu gom rác và tôi muốn có thể tái sử dụng chúng tại thời điểm tôi cần cập nhật trạng thái của chúng sang cơ sở dữ liệu. Nó chỉ có ý nghĩa để cho họ được thu gom rác thải, khi các ObservableCollection whence họ đến là ra khỏi phạm vi. –
Bạn có thể phân lớp ObservableCollection và thêm IDispose để thông báo mã của bạn. Nó sẽ đặt một gánh nặng trên mã khách hàng của bạn mặc dù để gọi IDispose. –