entity-framework orm entity-framework-4.1 ef-code-first dynamic-proxy

¿Debo habilitar o deshabilitar los proxies dinámicos con entity framework 4.1 y MVC3?



entity-framework orm (5)

¿Podría alguien ofrecer algún consejo o señalar algunos blogs / artículos que podrían ayudar a tomar esta decisión? Los proxies me parecen muy extraños y dudo en usarlos. Me gusta la capacidad de controlar la carga diferida mediante el uso de propiedades virtuales en mi modelo, pero esos son prácticamente todos los beneficios que puedo ver. Mi aplicación es una aplicación web simple de MVC y no necesito conectar ningún gancho al contexto para cuando las entidades experimenten un cambio de estado.

De todos modos, aquí está mi muy limitada lista de pros y contras en este momento, avíseme si estoy fuera de base con algo de esto.

Pros

  • En ''Guardar'' o ''Actualizar'', me pongo sin problemas con ''Aplicar'' Cambios ''
  • Lazy-Loading configuration es muy fácil.

Contras

  • Nunca utilicé poderes para mis entidades, este es un cambio en el enfoque que me parece incómodo para mí y para los demás miembros del equipo.
  • Difícil de depurar.
  • Requiere código adicional si quiero serializar / deserializar
  • En ''Guardar'' o ''Actualizar'', el proxy debe ser el mismo objeto que se recuperó del contexto.

Aunque los proxies dinámicos tienen algunas características agradables, en realidad pueden crear muchos errores extraños y desconocidos.

Por ejemplo, mantuve una variable privada de una entidad en una de mis clases (estaba implementando un proceso por lotes) y estaba recorriendo algunos millones de registros, procesándolos e insertándolos en lotes, recreando el contexto de datos cada n-registros para limpia la memoria Aunque NUNCA utilicé la variable privada, EF la estaba vinculando a mis nuevos objetos (había una referencia a través de una propiedad de navegación) aunque solo estaba configurando el Id. De referencia.

Esto causó que todos los objetos permanecieran en la memoria durante todo el tiempo que el proceso se estaba ejecutando. Tuve que usar AsNoTracking y deshabilitar los proxies para que el proceso funcione como se esperaba y la memoria y el rendimiento vuelvan a los niveles normales. Tenga en cuenta que los proxies también hacen referencia al contexto que los creó y esto puede mantener en la memoria enormes gráficos de entidades, es casi imposible depurarlo

Por lo tanto, creo que debe desactivar globalmente los proxies y habilitarlos en fragmentos de código pequeños y contenidos. Es muy peligroso e imposible depurar estos problemas, especialmente cuando tienes una gran codificación de equipos.

El seguimiento de cambios es bueno, podría justificar el uso en algunos lugares. La carga diferida puede ser un gran problema en el rendimiento y la serialización a menos que sepa lo que está haciendo. Prefiero la carga ansiosa o explícita en todo momento.


Para cualquiera que use Entity Framework 5, asegúrese de revisar el artículo Consideraciones de rendimiento . Sections 5 NoTracking Queries y 8 Loading Related Entities ofrecen la información que necesita para tomar una decisión informada. Aclamaciones.


Si habla de proxies dinámicos en EF, hay dos tipos diferentes para distinguir:

  • Proxies para carga lenta
  • Proxies para el seguimiento de cambios

Por lo general, un proxy de seguimiento de cambios también puede servir como un proxy para la carga diferida. Lo opuesto no es verdad. Esto se debe a que los requisitos para los proxies de seguimiento de cambios son mayores, especialmente todas las propiedades, también las propiedades escalares, deben ser virtual . Para la carga lenta, basta con que las propiedades de navegación sean virtual .

El hecho de que un proxy de seguimiento de cambios siempre permita aprovechar la carga lenta es la razón principal por la cual el DbContext tiene este indicador de configuración:

DbContext.Configuration.LazyLoadingEnabled

Esta bandera es verdadera por defecto. Establecerlo en false inhabilita la carga diferida incluso si se crean proxies. Esto es especialmente importante si está trabajando con proxies de seguimiento de cambios, pero no quiere usar esos proxies para la carga diferida también.

La opción ...

DbContext.Configuration.ProxyCreationEnabled

... deshabilita completamente la creación de proxy, para el seguimiento de cambios y la carga diferida también.

Ambas banderas solo tienen un significado si sus clases de entidad cumplen los requisitos para crear un seguimiento de cambio o proxies de carga diferida.

Ahora, conoces el propósito de los proxies dinámicos de carga diferida. Entonces, ¿por qué debería uno usar proxies de seguimiento de cambios dinámicos?

De hecho, la única razón por la que estoy enterado es el rendimiento . Pero esta es una razón muy fuerte. Comparando el seguimiento de cambios basado en proxy con la diferencia de rendimiento, la diferencia de rendimiento es enorme: de mis mediciones un factor de 50 a 100 es realista (tomado de un método que requirió alrededor de una hora para 10000 entidades con seguimiento de cambios basado en instantáneas y de 30 a 60 segundos después de hacer que todas las propiedades sean virtuales para habilitar los proxys de seguimiento de cambios). Esto está obteniendo un factor importante si tiene alguna aplicación que procesa y cambia muchas (digamos más de 1000) entidades. En una aplicación web donde posiblemente solo tenga operaciones Crear / Cambiar / Eliminar en entidades individuales en una solicitud web, esta diferencia no importa tanto.

En casi todas las situaciones, puede aprovechar la carga ansiosa o explícita para lograr el mismo objetivo si no desea trabajar con proxies de carga diferidos. El rendimiento de la carga diferida basada en proxy o la carga explícita no basada en proxy es el mismo porque básicamente la misma consulta ocurre cuando se cargan las propiedades de navegación; en el primer caso, el proxy hace la consulta, en el segundo caso su código escrito a mano. Por lo tanto, puede vivir sin proxies de carga perezosos sin perder demasiado.

Pero si desea un rendimiento razonable para procesar muchas entidades, no hay alternativa para cambiar los EntityObject proxy de seguimiento, aparte de usar entidades derivadas EntityObject en EF 4.0 (no una opción en EF 4.1 porque está prohibido cuando usa DbContext ) o no usar Entity Framework en absoluto.

Editar (mayo de 2012)

Mientras tanto, he aprendido que hay situaciones en las que los proxies de seguimiento de cambios no son más rápidos o incluso peores en el rendimiento en comparación con el seguimiento basado en instantáneas.

Debido a estas complicaciones al usar proxies de seguimiento de cambios, la forma preferida es usar el seguimiento de cambios basado en instantáneas por defecto y usar proxies cuidadosamente (después de hacer algunas pruebas) solo en situaciones donde se requiere un alto rendimiento y donde resultan ser más rápidos que las instantáneas cambio de seguimiento.


Sugeriría NO usar proxies. La creación de proxy dinámico rompe o crea complicaciones para los componentes que dependen de la verificación del tipo de tiempo de ejecución.

Automapper, por ejemplo, lanzará un error de tipo no coincidente / tipo inesperado durante el tiempo de ejecución ya que sus entidades tendrán tipos de proxy generados dinámicamente durante el tiempo de ejecución, y no los tipos que pasó al configurar la automatización.


Use Automapper 4.2.1. La nueva versión no está teniendo DynamicMap

var parents = parentsRepo.GetAll().ToList(); Mapper.CreateMap<Parent,ParentDto>(); var parentsDto = Mapper.DynamicMap<List<ParentDto>>(parents);