Votre description (1) est correct, mais il est un exemple de chargement rapide plutôt que de chargement paresseux.
Votre description de (2) est incorrecte. (2) n'utilise techniquement aucune charge, mais utilisera Lazy Loading si vous essayez d'accéder à des valeurs non-scalaires sur vos FlaggedDates.
Dans les deux cas, vous avez raison qu'aucune donnée ne sera chargée à partir de votre magasin de données tant que vous n'essayez pas de "faire quelque chose" avec les _flaggedDates. Cependant, ce qui se passe est différent dans chaque cas.
(1): Chargement rapide: dès que vous commencez votre boucle for
, chacun des objets que vous avez spécifiés sera extrait de la base de données et intégré dans une gigantesque structure de données en mémoire. Ce sera une opération très coûteuse, tirant une énorme quantité de données de votre base de données. Cependant, tout se passe dans un seul aller-retour de base de données, avec une seule requête SQL exécutée.
(2): Chargement paresseux: Lorsque votre boucle for
commence, elle ne chargera que les objets FlaggedDates. Cependant, si vous accédez à des objets connexes dans votre boucle for
, ces objets ne seront pas encore chargés dans la mémoire. La première tentative d'extraction des scheduledSchools pour un FlaggedDate donné aboutira soit à un nouveau roundtrip de base de données pour récupérer les écoles, soit une exception est levée car votre contexte a déjà été éliminé. Puisque vous seriez en train d'accéder à la collection scheduledSchools à l'intérieur d'une boucle for
, vous auriez un nouveau round round trip pour chaque FlaggedDate que vous avez initialement chargé au début de la boucle for
.
Reponse aux commentaires
Chargement Lazy est Désactiver pas la même que l'activation Désireuse Chargement.Dans cet exemple:
context.ContextOptions.LazyLoadingEnabled = false;
var schools = context.FlaggedDates.First().scheduledSchools;
La variable schools
contiendra un EntityCollection vide, parce que je ne les ai pas Include
dans la requête initiale (FlaggedDates.First()), et je désactivé le chargement paresseux afin qu'ils ne pouvaient pas être chargé après l'exécution de la requête initiale.
Vous avez raison de dire que le where d.dateID == 2
signifierait que seuls les objets liés à cet objet FlaggedDate spécifique seraient extraits. Cependant, en fonction du nombre d'objets liés à cette FlaggedDate, vous pourriez vous retrouver avec beaucoup de données passer par-dessus ce fil. Cela est dû à la façon dont EntityFramework construit sa requête SQL. Les résultats de requête SQL sont toujours dans un format tabulaire, ce qui signifie que vous devez avoir le même nombre de colonnes pour chaque ligne. Pour chaque objet scheduledSchool, il doit y avoir au moins une ligne dans le jeu de résultats, et comme chaque ligne doit contenir au moins une valeur pour chaque colonne, chaque valeur scalaire de votre objet FlaggedDate se répète. Donc, si vous avez 10 scheduledSchools et 10 interviews associés à votre FlaggedDate, vous aurez 20 lignes contenant chacune une valeur scalaire sur FlaggedDate. La moitié des lignes aura des valeurs nulles pour toutes les colonnes ScheduledSchool, et l'autre moitié aura des valeurs nulles pour toutes les colonnes Interviews.
Lorsque cela devient vraiment mauvais, cependant, c'est si vous allez "profond" dans les données que vous incluez. Par exemple, si chaque ScheduledSchool avait une propriété students
, que vous incluiez également, alors vous auriez soudainement une ligne pour chaque Student dans chaque ScheduledSchool, et sur chacune de ces lignes, chaque valeur scalaire pour l'ScheduledSchool de Student serait incluse (même mais seulement les valeurs de la première ligne finissent par être utilisées), ainsi que toutes les valeurs scalaires de l'objet FlaggedDate original. Ça peut s'ajouter rapidement.
Il est difficile d'expliquer par écrit, mais si vous regardez les données réelles revenant d'une requête avec plusieurs Include
s, vous verrez qu'il y a beaucoup de données en double. Vous pouvez utiliser LinqPad pour voir les requêtes SQL générées par votre code EF.
EntityFramework utilise un chargement impatient/paresseux (terme générique utilisé pour le chargement des données) pour extraire les objets et collections associés. Deffered Query Execution est un artefact de LINQ qui permet aux requêtes d'être plus flexibles (elles peuvent ne pas être exécutées du tout dans certains scénarios). – jwize