En nuestra aplicación comercial de niveles múltiples tenemos ObservableCollections
de Entidades de seguimiento automático que se devuelven de las llamadas de servicio.¿Cómo hacer un seguimiento de los objetos eliminados de un ObservableCollection en escenarios CRUD?
La idea es que queremos poder obtener entidades, agregarlas, actualizarlas y eliminarlas del lado del cliente de recopilación, y luego enviar estos cambios al lado del servidor, donde se conservarán en la base de datos.
Entidades de seguimiento propio, como su nombre podría sugerir, realizar un seguimiento de su estado. Cuando se crea un STE nuevo, tiene el estado Agregado, cuando modifica una propiedad, establece el estado Modificado, también puede tener el estado Eliminado, pero este estado no se establece cuando la entidad se elimina de un ObservableCollection
(obviamente). Si desea este comportamiento, debe codificarlo usted mismo.
En mi implementación actual, cuando una entidad se elimina de la ObservableCollection
, lo guardo en una colección de sombra, por lo que cuando el ObservableCollection
se envía de vuelta al servidor, puedo enviar los elementos eliminados a lo largo de, por lo Entity Framework sabe para borrarlos
Algo a lo largo de las líneas de:
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>());
}
};
}
Ahora bien, si el usuario decide guardar sus cambios en el servidor, que puede obtener la lista de elementos eliminados, y enviarlos junto:
ObservableCollection<Customer> customers = MyServiceProxy.GetCustomers();
customers.RemoveAt(0);
MyServiceProxy.UpdateCustomers(customers);
En este punto, el método UpdateCustomers
verificará mi colección de instantáneas si se eliminaron algunos elementos y los enviará al lado del servidor.
Este enfoque funciona bien, hasta que comienzas a pensar en el ciclo de vida de estas colecciones de sombras. Básicamente, cuando el ObservableCollection
es basura recolectada, no hay forma de saber que tenemos que eliminar la colección de sombras de nuestro diccionario.
Se me ocurrió una solución complicada que básicamente hace la gestión manual de la memoria en este caso. Guardo un WeakReference
en el ObservableCollection
y cada pocos segundos compruebo si la referencia está inactiva, en cuyo caso elimino la colección de sombras.
Pero esto parece una solución terrible ... Espero que el genio colectivo de StackOverflow pueda arrojar luz sobre una mejor solución.
EDIT:
Al final me decidí a ir con la subclasificación de la ObservableCollection
. Se genera el código proxy del servicio, por lo que era una tarea relativamente simple cambiarlo para devolver mi tipo derivado.
¡Gracias por toda la ayuda!
¿Por qué no mantener referencias débiles a las entidades en sí, en lugar de la colección? Entonces no necesitas jugar con la colección ya que las entidades son eliminadas; solo asegúrese de que las referencias estén en vivo cuando itere. –
Mantener referencias débiles a las entidades, en lugar de agregarlas a una colección paralela, efectivamente permitiría que sean basura, y quiero poder reutilizarlas en el punto donde necesito actualizar su estado a la base de datos. Solo tiene sentido dejar que sean basura, cuando el ObservableCollection de donde vinieron está fuera del alcance. –
Podría subclasificar ObservableCollection y agregar IDispose que notifique su código. Sin embargo, sería una carga para el código de su cliente llamar a IDispose. –