Entity Framework - Quelle est la différence entre utiliser Include/eager loading et lazy loading?

j'ai essayé de me familiariser avec le cadre de L'entité. La plupart de cela semble simple, mais je suis un peu confus sur la différence entre le chargement eager avec la méthode Include et le chargement paresseux par défaut. Les deux semblent comme ils chargent entités connexes, donc à la surface, il semble qu'ils font la même chose. Ce qui me manque?

18
demandé sur Major Productions 2010-08-17 21:27:55

4 réponses

disons que vous avez deux entités avec une relation de un à plusieurs: Le Client et la commande, où chaque client peut avoir plusieurs commandes.

lors du chargement d'une entité client, Entity Framework vous permet soit de charger avec empressement soit de charger avec paresse la collecte des commandes du client. Si vous choisissez de charger la collection de commandes, lorsque vous récupérez un client hors du cadre D'entité de base de données va générer SQL qui récupère l'information du client et le Ordre du client en une seule interrogation. Cependant, si vous choisissez de charger paresseusement la collection de commandes, lorsque vous récupérez un client hors du cadre D'entité de base de données va générer SQL que extrait les informations du client (le cadre D'entité générera alors un État SQL séparé si vous accédez à la collecte des commandes du client plus tard dans votre code).

déterminer quand utiliser le chargement rapide et quand utiliser le chargement paresseux tout se résume à ce que vous attendez de faire avec le les entités que vous récupérez. Si vous savez que vous avez seulement besoin des informations D'un client, alors vous devriez charger paresseusement la collecte des commandes (de sorte que la requête SQL peut être efficace en récupérant seulement les informations du client). Inversement, si vous savez que vous aurez besoin de parcourir les commandes D'un client, alors vous devriez impatiemment-charger les commandes (de sorte que vous économiserez vous-même un coup supplémentaire de la base de données une fois que vous accédez aux commandes du client dans votre code).

P.S. soyez très prudent lorsque vous utilisez le chargement paresseux comme il peut conduire à la (N+1 problème. Par exemple, disons que vous avez une page qui affiche une liste de clients et leurs commandes. Cependant, vous décidez d'utiliser paresseux-chargement lors de la récupération des commandes. Lorsque vous itérez au-dessus de la collection de clients, puis au-dessus des commandes de chaque client, vous effectuerez un hit de base de données pour chaque client à la charge paresseuse dans leur collection de commandes. Cela signifie que pour N clients, vous aurez N+1 accès à la base de données (1 accès à la base de données pour charger tous les clients, puis N accès à la base de données pour charger chaque de leurs commandes) au lieu de juste 1 Base de données avait frappé si vous aviez utilisé chargement eager (qui aurait récupéré tous les clients et leurs commandes dans une requête).

30
répondu Kevin Pang 2010-08-17 17:39:54

si vous venez de SQL world pensez à rejoindre.

si vous devez afficher dans une grille 10 commandes et le client qui a passé la commande vous avez 2 choix:

1) LAZY LOAD (=11 queryes = SLOW PERFORMANCES)

EF seront tiré une requête pour récupérer les commandes et une requête pour chaque commande pour récupérer les données du client.

Select * from order where order=1
+
10 x (Select * from customer where id = (order.customerId))

1) EAGER LOAD ( = 1 query = HIGH PERFORMANCES)

EF va tirer un simple requête pour récupérer les commandes et les clients avec une JOINTURE.

Select * from orders INNER JOIN customers on orders.customerId=customer.Id where order=1

PS: Lorsque vous récupérez un objet à partir de la base de données, l'objet est stocké dans un cache pendant que le contexte est actif. Dans l'exemple que j'ai fait avec LAZY LOAD, si les 10 commandes concernent le même client vous ne verrez que 2 requêtes car lorsque vous demandez à EF de récupérer un objet, EF vérifiera si l'objet est dans le cache et s'il le trouve, il ne lancera pas une autre requête SQL vers DB.

17
répondu Marco Staffoli 2010-11-11 21:47:47

Une question importante est la sérialisation. Microsoft recommande de ne pas utiliser le chargement paresseux par défaut si vous avez affaire à des objets sérialisés. La sérialisation fait que toutes les propriétés connexes sont appelées, ce qui peut déclencher une réaction en chaîne des entités apparentées qui sont interrogées. Cela entre vraiment en jeu si vous retournez des données JSON d'un contrôleur. Les données JSON sont évidemment sérialisées. Vous souhaitez soit retourner des données immédiatement via Eager ou désactiver la charge dans le contexte et employer Chargement paresseux explicite.

0
répondu Charles Owen 2018-03-28 05:37:11