Entity Framework: ¿Cómo deshabilitar la carga diferida para una consulta específica?

88

¿Hay alguna forma de deshabilitar la carga diferida para consultas específicas en Entity Framework 6? Quiero usarlo con regularidad, pero a veces quiero desactivarlo. Estoy usando propiedades virtuales para cargarlas de forma diferida.

Marco Alves
fuente
20
establecer context.Configuration.LazyLoadingEnabled = false; antes de la consulta que desea ejecutar
Karthik Ganesan
5
¿Podría simplemente establecer el valor this.Configuration.LazyLoadingEnabled = false;y luego volver a establecerlo this.Configuration.LazyLoadingEnabled = true;? Además, puede leer este msdn.microsoft.com/en-us/data/jj574232.aspx
user1477388
1
gracias @KarthikGanesan. Funcionó como se esperaba.
Marco Alves
@KarthikGanesan ¿Puedes poner tu comentario como respuesta? Está funcionando muy bien :)
Sampath
1
Agregó el comentario como respuesta @Sampath
Karthik Ganesan

Respuestas:

76

establezca el siguiente código antes de la consulta que desea ejecutar

context.Configuration.LazyLoadingEnabled = false;
Karthik Ganesan
fuente
40

Puede deshabilitar la carga diferida para consultas específicas de la siguiente manera:

public static Cursos GetDatosCursoById(int cursoId)
{
    using (var bd = new AcademyEntities())
    {
        try
        {
            bd.Configuration.ProxyCreationEnabled = false;
            return bd.Cursos.FirstOrDefault(c => c.cursoId == cursoId);
        }
        catch (Exception ex)
        {
            return null;
        }
    }
}
William Ballesteros
fuente
20

Puede que me esté perdiendo algo aquí, pero en lugar de cambiar la configuración cada vez, podría usar otro enfoque .Include() solo en aquellas consultas en las que desea cargar ansiosamente?

Supongamos que tenemos una Productclase que tiene una propiedad de navegación para una Colourclase, puede cargar la Colourpara una Productcomo esta:

var product = _context.Products
    .Where(p => p.Name == "Thingy")
        .Include(x => x.Colours)
        .ToList();
Parrybird
fuente
1
¡Para mí esta es la mejor respuesta aquí!
Ian
Esto se queda corto si solo desea cargar "productos", sin ningún tipo de inclusión.
Mackan
Entonces, ¿querría obtener 'Productos' sin ninguno de sus objetos relacionados o 'Productos con todos sus objetos relacionados?'
Parrybird
1
Respuesta mucho más útil. Esto controla las tablas subordinadas específicas que se cargan en el punto donde se está construyendo la consulta. Para cualquier problema del mundo real, este debe ser el camino a seguir.
Richard Petheram
5
Es útil de una manera diferente ... si lo hace de esta manera, todavía podría tener una carga diferida para otra colección de 'Productos'. En realidad, deshabilitar la carga diferida es más eficaz para garantizar que todos los datos necesarios se obtengan por adelantado y evita la creación de cuellos de botella de rendimiento ocultos.
Doug
15

Vaya a las propiedades de su diagrama y busque una propiedad designada para carga diferida y desactívela.

Si está usando el código primero, vaya a su área de configuración y deshabilítelo desde allí con:

this.Configuration.LazyLoadingEnabled = false;
Juan
fuente
6
Mucha gente está visitando esta pregunta y quiero decir que la gente NO ESCRIBA CONSULTAS SIN MIRAR EL PLAN DE EJECUCIÓN. Siempre sepa lo que envía su código a la base de datos o tendrá problemas de rendimiento. Puede usar linq pad u otras herramientas para ver la consulta real y verificar.
Juan
11

En EF Core: context.ChangeTracker.LazyLoadingEnabled = false;

Por esta respuesta .

Matt Jenkins
fuente
3

Otro enfoque para otra versión de EF (Entity Framework 5)

//Note: ContextOptions instead of ChangeTracker or Configuration
context.ContextOptions.LazyLoadingEnabled = false; 
fubo
fuente
Cuando contextes una ObjectContext, el predecesor más o menos obsoleto de su envoltorio, DbContext.
Gert Arnold
2

Suponga que tiene esto:

IOrderedQueryable<Private.Database.DailyItem> items;
using (var context = new Private.Database.PrivateDb())
{
    context.Configuration.LazyLoadingEnabled = false;
    items = context.DailyItem.OrderBy(c => c.sortOrder).OrderByDescending(c => c.isFavorite);
}

Aún obtendría carga diferida, a pesar de la configuración explícita de no hacerlo. La solución es fácil, cámbielo a esto:

List<Private.Database.DailyItem> items;
using (var context = new Private.Database.PrivateDb())
{
    // context.Configuration.LazyLoadingEnabled = false;
    items = context.DailyItem.OrderBy(c => c.sortOrder).OrderByDescending(c => c.isFavorite).ToList();
}
Fortaleza
fuente