2010-06-03 22 views
55

Parece que la carga diferida está habilitada de manera predeterminada en EF4. Al menos, en mi proyecto, puedo ver que el valor deInhabilitar la carga diferida de forma predeterminada en Entity Framework 4

dataContext.ContextOptions.LazyLoadingEnabled 

es verdadero por defecto. No deseo la carga lenta y no quiero tener que escribir:

dataContext.ContextOptions.LazyLoadingEnabled = false; 

cada vez que obtengo un nuevo contexto. Entonces, ¿hay alguna manera de desactivarlo por defecto, por ejemplo, en todo el proyecto?

Respuesta

63

La siguiente respuesta se refiere a la base de datos -Primera o Modelo-Primera flujo de trabajo (los únicos dos flujos de trabajo que estaban disponibles con Entity Framework (versión < = 4,0) cuando se hizo la pregunta). Si está utilizando el flujo de trabajo Code-First (que está disponible desde la versión EF> = 4.1), proceda con ssmith's answer a esta pregunta para una solución correcta.


El archivo edmx tiene en la definición <ConceptualModel> y <EntityContainer> un atributo para la carga diferida donde se puede establecer la carga diferida generalmente en false:

<EntityContainer Name="MyEntitiesContext" annotation:LazyLoadingEnabled="false"> 

Esto crea la siguiente configuración en el constructor ObjectContext:

public MyEntitiesContext() : base("name=MyEntitiesContext", "MyEntitiesContext") 
{ 
    this.ContextOptions.LazyLoadingEnabled = false; 
    OnContextCreated(); 
} 

Mi ejemplo no significa que el generado ObjectContext (o)en versiones EF más nuevas) debe editarse manualmente (lo que se sobrescribirá con cada actualización de modelo de la base de datos, como señaló ctorx) pero que el elemento EntityContainer en la sección edmx:ConceptualModels del archivo EDMX se debe editar agregando el atributo annotation:LazyLoadingEnabled="false" - ya sea manualmente en un editor XML o en la página de propiedades de la superficie del diseñador donde esta opción también está disponible. Esta modificación del archivo EDMX generará automáticamente la clase de contexto con la opción de carga lenta diferida en el constructor como se muestra arriba. La modificación del archivo EDMX en sí no se sobrescribe cuando el modelo se actualiza desde la base de datos.

+0

Perfecto, gracias. –

+15

Esto requiere que modifique el código generado, que se sobrescribirá si modifica su modelo. Considere poner una ObjectContextFactory en su lugar y realice el cambio en la fábrica. De esta forma, solo está configurando la opción una vez y no está cambiando el código generado automáticamente. – ctorx

+0

@ctorx - AFAICT una opción más simple que la fábrica sería simplemente implementar el OnContextCreated parcial para desactivar la carga diferida? ¿O me estoy perdiendo algo? –

58

Escribí una muestra rápida que muestra how the new Lazy Loading features work with EF Code First. El logro de lo que quiere en el Código Primer modelo es simplemente una cuestión de añadir una línea a su constructor de DbContext, así:

public BlogContext() 
{ 
    this.Configuration.LazyLoadingEnabled = false; 
} 
+10

No es que importe mucho, pero tanto ': base()' y 'this' son redundantes en este código. –

+0

En términos de funcionalidad, sí, en términos de legibilidad creo que a veces es útil incluir 'this'. Sin embargo, estoy de acuerdo en 'base()', no puedo pensar en una razón para agregar eso. –

+0

Sí, no estoy seguro de por qué base() estuvo alguna vez en eso. Remoto. – ssmith

24

Si usted puede utilizar Código EF4 En primer lugar, ¿no? Entonces, en la Inicialización de su contexto, está la anulación de 'OnModelCreated'.

En este método, simplemente llamé y configuré la propiedad y todo se resolvió.

protected override void OnModelCreating(DbModelBuilder modelBuilder) { 
    base.Configuration.LazyLoadingEnabled = false; 
} 

Mi modelo es ahora mucho más apetecible. La carga lenta es genial ... pero no cuando no la quieres. Y cuando comienzas a tener referencias circulares, es simplemente ridículo.

+4

Esto no funcionará porque inhabilitará la carga diferida solo para la instancia de contexto que crea el modelo (generalmente la primera instancia utilizada después del inicio de la aplicación). Para todas las instancias de contexto posteriores 'OnModelCreating' no se llama y' LazyLoadingEnabled' tendrá el valor predeterminado, que es 'true'. – Slauma

+0

@Slauma - He acertado el mismo problema hoy, y he editado esta respuesta (ya que es la aceptada) para cambiarla a la configuración en el ctor en su lugar. Si tuviera el poder de cambiar la respuesta aceptada de esta a la tuya, lo haría en su lugar. :) –

+1

@JamesManning: Esta pregunta tiene una historia extraña. Mi respuesta fue aceptada hace unos meses. Pero mi respuesta no es buena (la crítica de ctorx es muy válida). Luego, el propietario de la pregunta movió el aceptar a este, que estuvo completamente equivocado hasta su edición. Además, es una respuesta para 'DbContext' que apareció mucho más tarde que la pregunta y los fragmentos de código en la pregunta siguen siendo para' ObjectContext'. Ahora lo ha editado con una respuesta correcta para 'DbContext', pero ahora es lo mismo que la respuesta de ssmith, que es más de un año mayor. Pero ambos no son una respuesta para 'ObjectContext'. Bastante loco :) – Slauma

21

También lo puede hacer del diseñador. Simplemente abra el archivo .edmx, haga clic derecho en cualquier lugar del modelo y elija Propiedades. Luego configure el LazyLoadingEnabled en falso. enter image description here

4

Si está modelando con código primero, simplemente elimine la palabra clave virtual en sus propiedades de referencia/objeto. Tener virtual en una referencia habilitará LazyLoading en esa referencia particular.

Cuestiones relacionadas