Cela peut être une question vraiment élémentaire, mais quelle est la bonne façon d'inclure plusieurs entités enfants lors de l'écriture d'une requête qui s'étend sur TROIS niveaux (ou plus)?
à- dire que j'ai 4 tables: Company
, Employee
, Employee_Car
etEmployee_Country
L'entreprise a une relation de 1: m avec l'employé.
L'employé a une relation 1: m avec Employee_Car et Employee_Country.
Si je veux écrire une requête qui renvoie les données des 4 tables, j'écris actuellement:
Company company = context.Companies
.Include("Employee.Employee_Car")
.Include("Employee.Employee_Country")
.FirstOrDefault(c => c.Id == companyID);
Il doit y avoir une manière plus élégante! Ceci est long et génère un SQL horrible
J'utilise EF4 avec VS 2010
linq
entity-framework
lazy-loading
Nathan Liu
la source
la source
//inside public static class Extensions public static IQueryable<Company> CompleteCompanies(this DbSet<Company> table){ return table .Include("Employee.Employee_Car") .Include("Employee.Employee_Country") ; } //code will be... Company company = context.Companies.CompleteCompanies().FirstOrDefault(c => c.Id == companyID); //same for next advanced method
EF 4.1 à EF 6
Il existe un type fortement typé
.Include
qui permet de spécifier la profondeur requise du chargement hâtif en fournissant des expressions Select à la profondeur appropriée:Le SQL généré dans les deux instances n'est toujours pas intuitif, mais semble suffisamment performant. J'ai mis un petit exemple sur GitHub ici
EF Core
EF Core a une nouvelle méthode d'extension
.ThenInclude()
, bien que la syntaxe soit légèrement différente :Selon la documentation, je garderais le «retrait» supplémentaire dans le
.ThenInclude
pour préserver votre santé mentale.Informations obsolètes (ne faites pas cela):
Le chargement de plusieurs petits-enfants peut être effectué en une seule étape, mais cela nécessite une inversion plutôt maladroite du graphique avant de descendre le nœud suivant (NB: cela ne fonctionne PAS avec
AsNoTracking()
- vous obtiendrez une erreur d'exécution):Je resterais donc avec la première option (un modèle de profondeur d'inclusion par entité feuille).
la source
Vous trouverez peut-être cet article intéressant disponible sur codeplex.com .
L'article présente une nouvelle façon d'exprimer des requêtes qui s'étendent sur plusieurs tables sous la forme de formes graphiques déclaratives.
De plus, l'article contient une comparaison approfondie des performances de cette nouvelle approche avec les requêtes EF. Cette analyse montre que GBQ surpasse rapidement les requêtes EF.
la source
Comment construire une requête LINQ to Entities pour charger directement des objets enfants, au lieu d'appeler une propriété Reference ou Load ()
Il n'y a pas d'autre moyen - sauf l'implémentation du chargement différé.
Ou chargement manuel ....
la source
Peut-être que cela aidera quelqu'un, 4 niveaux et 2 enfants à chaque niveau
la source