In unserer mehrschichtigen Geschäftsanwendung haben wir ObservableCollections
Self-Tracking Entities, die von Serviceaufrufen zurückgegeben werden.Wie verfolgen Sie Objekte, die in CRUD-Szenarien aus einer ObservableCollection gelöscht wurden?
Die Idee ist, wir in der Lage sein, Entitäten zu erhalten, hinzufügen, aktualisieren und entfernen sie von der Sammlung Client-Seite, und senden Sie diese Änderungen an die Server-Seite, wo sie in der Datenbank gespeichert werden.
Self-Tracking-Entitäten, wie ihr Name vermuten lässt, verfolgen ihren Zustand selbst. Wenn ein neues STE erstellt wird, hat es den hinzugefügten Status, wenn Sie eine Eigenschaft ändern, legt es den Status Modified fest, es kann auch gelöschten Status haben, aber dieser Status wird nicht festgelegt, wenn die Entität von ObservableCollection
entfernt wird (natürlich). Wenn Sie dieses Verhalten wollen, müssen Sie es selbst programmieren.
In meiner aktuellen Implementierung, wenn ein Unternehmen aus den ObservableCollection
entfernt wird, ich halte es in einem Schatten Sammlung, so dass, wenn die ObservableCollection
zurück an den Server gesendet, sie entlang die gelöschten Objekte senden kann, so Entity Framework kennt um sie zu löschen.
Etwas entlang der Linien von:
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>());
}
};
}
Nun, wenn der Benutzer seine Änderungen an den Server zu speichern entscheidet, kann ich die Liste der entfernten Einzelteile erhalten, und senden Sie sie an:
ObservableCollection<Customer> customers = MyServiceProxy.GetCustomers();
customers.RemoveAt(0);
MyServiceProxy.UpdateCustomers(customers);
An dieser Stelle wird die Methode meine Shadow-Sammlung überprüfen, wenn Elemente entfernt wurden, und sie an die Serverseite senden.
Dieser Ansatz funktioniert gut, bis Sie beginnen, über den Lebenszyklus dieser Schattenkollektionen nachzudenken. Wenn der ObservableCollection
Müll gesammelt wird, gibt es keine Möglichkeit zu wissen, dass wir die Schattensammlung aus unserem Wörterbuch entfernen müssen.
Ich kam mit einer komplizierten Lösung, die in diesem Fall grundsätzlich manuelle Speicherverwaltung macht. Ich behalte eine WeakReference
an die ObservableCollection
und alle paar Sekunden überprüfe ich, ob die Referenz inaktiv ist, in welchem Fall ich die Schattensammlung entfernen.
Aber das scheint eine schreckliche Lösung ... Ich hoffe, dass das kollektive Genie von StackOverflow eine bessere Lösung beleuchten kann.
EDIT:
Am Ende entschied ich mich mit Subklassen die ObservableCollection
zu gehen. Der Dienstproxycode wird generiert, sodass es eine relativ einfache Aufgabe war, ihn so zu ändern, dass er meinen abgeleiteten Typ zurückgibt.
Danke für die Hilfe!
Warum nicht schwache Referenzen auf die Entitäten selbst, anstatt die Sammlung zu halten? Dann müssen Sie nicht an der Sammlung herumfummeln, wenn Entitäten entfernt werden. Stellen Sie nur sicher, dass die Referenzen bei der Iteration aktiv sind. –
Wenn Sie schwache Verweise auf Entitäten beibehalten, anstatt sie zu einer Shadow-Auflistung hinzuzufügen, können sie effektiv als Garbage Collected erfasst werden, und ich möchte sie an dem Punkt wiederverwenden können, an dem ich ihren Status in der Datenbank aktualisieren muss. Es macht nur Sinn, sie als Garbage Collected zu betrachten, wenn die ObservableCollection, aus der sie stammen, nicht mehr verfügbar ist. –
Sie könnten ObservableCollection ableiten und IDispose hinzufügen, die Ihren Code benachrichtigt. Es würde Ihren Client-Code jedoch belasten, IDispose aufzurufen. –