2009-12-22 19 views
5

Estamos escribiendo una aplicación WPF utilizando Entity framework (Silverlight con servicios de RIA para ser precisos). Estamos utilizando un ObjectContext compartido a través de la aplicación para que podamos aprovechar el intercambio de datos entre los módulos.Entity Framework ObjectContext en la aplicación windows/WPF/Silverlight

El problema es que si el usuario abre durante su trabajo, digamos las ventas históricas, se carga al ObjectContext y permanece allí hasta el final de la aplicación. Entonces otro patrón debería ser usado.

Sé que ObjectContexts se debe utilizar como unidad de trabajo individual. Pero entonces, ¿cómo se permite que otras partes de la aplicación sepan que algo ha cambiado y que deberían volver a cargar sus datos?

Editar: Ok, EventAggregator, pero entonces, esto haría que todas las demás partes volvieran a cargar sus datos (probablemente la mayoría duplicados). También probablemente se necesitarían muchos eventos para todos los tipos de grupos de entidades.

¿Cómo resuelves estos problemas? Mi solución actual es una especie de compromiso: utilice un ObjectContext compartido para los datos centrales utilizados por la aplicación completa, de modo que puedan compartirse y actualizarse automáticamente. Y para la gran cantidad de datos, use un nuevo ObjectContext separado. Alguna mejor idea?

¿Hay alguna manera de "liberar" entidades de su DataContext para que Garbage collector pueda hacer su trabajo y liberar la memoria?

Respuesta

2

Espera, ¿es WPF o Silverlight? En este caso, son muy diferentes y mi respuesta sería diferente.

WPF Solución

En WPF me gustaría crear una sola forma ObjectContext por. De esta manera, el contexto solo durará tanto como la forma misma. A continuación, debe implementar un sistema de eventos para que cuando guarde los cambios en una entidad pueda alertar a los otros formularios que pueden necesitar para actualizar sus datos (INotifyPropertyChanged, por ejemplo). Oren Eini wrote a pretty good article on this architecture using NHibernate in MSDN magazine. Debería poder obtener el concepto de arquitectura de su artículo.

Silverlight Solución

Ahora, Silverlight es diferente. Silverlight esencialmente solo le permite tener un formulario en su aplicación. Sí, hay algunos trucos que puede realizar para navegar por la vista de raíz del formulario a diferentes "páginas", pero sigue siendo solo un formulario y el usuario no puede abrir varias ventanas en un Silverlight RIA. Por este motivo, crearía un .NET RIA Services ObjectContext por instancia Silverlight RIA. Recuerde, RIA Services no es una conexión real a su base de datos, es solo un caché y un objeto de seguimiento de cambios vinculado a un servicio web. Por lo tanto, es perfectamente aceptable dejar este objeto en existencia por períodos de tiempo más largos porque no está atando ningún recurso del servidor. Si su RIA de Silverlight abre varias ventanas del navegador o tiene más de un objeto de Silverlight, entonces debe tener un ObjectContext por instancia de Silverlight.

En el servidor, utiliza Entity Framework ObjectContext en el servicio web y solo debe durar una solicitud. Cuanto más apátridas pueda hacer sus servicios, más escalables y eficientes serán. Desea abrir su EF ObjectContext, usarlo y cerrarlo lo antes posible.


EDIT:

Si todo lo que están queriendo hacer es separar un objeto del contexto del objeto, a continuación, puedes usar el método context.Detach(entity). Puede encontrar un example of how to do this on MSDN.

+0

Con esta aplicación, estamos hablando de Silverlight. Usando Prism/Caliburn, creo que no es un problema tener un solo ObjectContext por vista (¿módulo?). De nuevo, el problema es: ¿qué pasa si hay una gran cantidad de datos para cargar al cliente? Por lo que estoy ahora, la mejor solución sería crear un ObjectContext compartido para las entidades básicas que se utilizan a través de toda la aplicación para que se sincronicen automáticamente, y ObjectContexts separados para la carga de gran cantidad de datos en, por ejemplo, algunos informes históricos. – gius

+0

No trataría de enviar bloques de datos realmente grandes al cliente. En cambio, me gustaría filtrar en el servidor y solo devolver los resultados que el cliente quiere ver en ese momento. Los humanos no pueden leer 100,000 registros, así que no envíes tantos a un humano. En cambio, deje que el problema sea una búsqueda/filtro y solo envíe los resultados al cliente. Si está creando informes, cree los datos de resumen agregados en el servidor. Por ejemplo, sería mejor calcular el volumen de ventas mensuales en el servidor y enviar un solo número al cliente de lo que se ve a 5000 registros de ventas. –

+0

Eso es cierto, pero si el usuario ve en cualquier momento durante la vida útil de la aplicación, digamos las páginas 1, 10 y 20, esos datos aún estarán en la memoria. Por otro lado, el uso de ObjectContext y paginación de datos separados podría resolver el problema de la gran cantidad de datos perdidos en la memoria. – gius

1

Puede usar el patrón de repositorio. Una capa adicional de abstracción entre UI y DAL.

Hacer colecciones de datos en el repositorio estáticas y observables. Luego, cada vez que el repositorio actualice alguno de ellos, la capa UI debería ponerse al día. Solo una idea.

+0

Esto no resuelve mi problema - las colecciones se quedarían en el cliente, así que si hay, por ejemplo, 1 GB de datos en la base de datos, tarde o temprano, también se cargará en el cliente. Por otro lado, esto podría mostrar una posible solución. ¡Gracias por la idea! – gius

0

Use ObservableCollections en ObjectContext. Use un evento que se desencadene en NotifyPropertyChange. Utilice un patrón de publicación/suscripción entre los modelos de visualización para informarles sobre el cambio y utilícelo para actualizar las otras vistas.

+1

Todas las colecciones creadas por EF son ObservableCollection y las entidades utilizan NotifyPropertyChanged. El problema es que no puedo usar ObjectContext solo durante todo el ciclo de vida de la aplicación porque luego no se liberan datos de la memoria una vez que se cargan en la aplicación. Por otro lado, el uso de ObjectContext por separado para cada acción causará problemas al actualizar los datos; los mismos datos se cargarán varias veces desde muchos lugares y la sincronización significaría eventos personalizados para cada tipo de datos. La pregunta principal es si hay algún marco/patrón para este problema. – gius

Cuestiones relacionadas