Su descripción de (1) es correcta, pero es un ejemplo de Eager Loading en lugar de Lazy Loading.
Su descripción de (2) es incorrecta. (2) técnicamente no utiliza ninguna carga, pero utilizará la Carga diferida si intenta acceder a valores no escalares en sus fechas marcadas.
En cualquier caso, tiene razón en que no se cargarán datos de su almacén de datos hasta que intente "hacer algo" con _flaggedDates. Sin embargo, lo que sucede es diferente en cada caso.
(1): Carga ansiosa: tan pronto como comience su ciclo for
, cada uno de los objetos que ha especificado se extraerá de la base de datos y se integrará en una gigantesca estructura de datos en memoria. Esta será una operación muy costosa, extrayendo una enorme cantidad de datos de su base de datos. Sin embargo, todo sucederá en una base de datos de ida y vuelta, con una única consulta SQL que se ejecutará.
(2): Carga diferida: Cuando comienza su ciclo for
, solo cargará los objetos FlaggedDates. Sin embargo, si accede a objetos relacionados dentro de su bucle for
, aún no tendrá esos objetos cargados en la memoria. El primer intento de recuperar las ScheduledSchools para un determinado FlaggedDate dará como resultado una nueva ida y vuelta a la base de datos para recuperar las escuelas, o una Excepción lanzada porque su contexto ya ha sido eliminado. Dado que accederá a la colección scheduledSchools dentro de un bucle for
, tendrá una nueva base de datos ida y vuelta por cada fecha marcada que cargó inicialmente al comienzo del bucle for
.
Reponse a los comentarios
Desactivación de Lazy Loading no es lo mismo que Habilitación Eager Cargando.En este ejemplo:
context.ContextOptions.LazyLoadingEnabled = false;
var schools = context.FlaggedDates.First().scheduledSchools;
La variable schools
contendrán una EntityCollection vacío, porque no lo hice Include
en la consulta original (FlaggedDates.First()), y la carga diferida I desactivada para que no pudiera ser cargado después de que la consulta inicial haya sido ejecutada.
Tiene razón en que el where d.dateID == 2
significa que solo se atraerán los objetos relacionados con ese objeto específico de FlaggedDate. Sin embargo, dependiendo de cuántos objetos estén relacionados con ese FlaggedDate, podría terminar con una gran cantidad de datos repasando ese cable. Esto se debe a la forma en que EntityFramework construye su consulta SQL. Los resultados de SQL Query están siempre en formato tabular, lo que significa que debe tener el mismo número de columnas para cada fila. Para cada objeto ScheduledSchool, debe haber al menos una fila en el conjunto de resultados, y dado que cada fila debe contener al menos algún valor para cada columna, se termina con cada valor escalar en su objeto FlaggedDate que se repite. Entonces, si tiene 10 SchoolsSchools y 10 entrevistas asociadas con su FlaggedDate, terminará con 20 filas que contienen cada valor escalar en FlaggedDate. La mitad de las filas tendrán valores nulos para todas las columnas de ScheduledSchool, y la otra mitad tendrá valores nulos para todas las columnas de Entrevistas.
Sin embargo, si esto llega a ser realmente malo, es si profundiza en los datos que está incluyendo. Por ejemplo, si cada escuela programada tenía una propiedad students
, que también incluyó, de repente tendría una fila para cada estudiante en cada escuela programada, y en cada una de esas filas, se incluiría cada valor escalar para la escuela programada del alumno (incluso aunque solo los valores de la primera fila terminan usándose), junto con cada valor escalar en el objeto FlaggedDate original. Puede sumarse rápidamente.
Es difícil de explicar por escrito, pero si nos fijamos en los datos reales que provienen de una consulta con múltiples Include
s, verá que hay una gran cantidad de datos duplicados. Puede usar LinqPad para ver las consultas SQL generadas por su código EF.
EntityFramework utiliza la carga impaciente/diferida (un término de software genérico para cómo se cargan los datos) para recuperar objetos y colecciones relacionados. La ejecución de consultas desviadas es un artefacto de LINQ que permite que las consultas sean más flexibles (es posible que no se ejecuten en absoluto en algunos escenarios). – jwize