2009-09-11 6 views
9

J'ai une table auto-référencée standard de Categories. Dans mon modèle d'entité j'ai fait des associations Children et Parent. Est-il possible de charger l'objet entier Category sans chargement paresseux?Envie de charger une table auto-référencée

Si j'utilise le code ci-dessous, il se charge uniquement au deuxième niveau.

db.Categories.MergeOption = System.Data.Objects.MergeOption.NoTracking; 

var query = from c in db.Categories.Include("Children") 
      where c.IsVisible == true 
      orderby c.SortOrder, c.Id 
      select c; 

Est-il possible de charger des références si tous les objets de catégorie sont déjà chargés?

Une méthode pour le charger est d'ajouter la propriété Children plusieurs fois

db.Categories.Include("Children.Children.Children.Children.Children") 

mais cela génère un code T-SQL très long fou et aussi il ne fait pas ce que je veux.

Répondre

1

Non, ce n'est pas possible. Considérez: Toutes les requêtes LINQ to Entities sont traduites en SQL. Quelle instruction SQL inclut une profondeur illimitée dans une hiérarchie auto-référencée? En SQL standard, il n'y en a pas. S'il y a une extension pour cela dans T-SQL, je ne sais pas ce que c'est, et je ne pense pas non plus que les fournisseurs d'EF le fassent.

+1

Mais si j'exécute la requête "SELECT * FROM Categories" j'ai chargé toute la table et aussi j'ai chargé toutes les catégories parent et enfants, parce qu'elles sont toutes dans une table. Donc, dans ce cas, il n'est pas très compliqué d'assigner ces enregistrements chargés aux propriétés référencées, ou pas? –

+1

Si vous itérez réellement toute la table, alors tous les objets * seront * en mémoire et * seront * déjà fixés, avec ou sans Include. Mais cela n'arrivera pas tant que vous n'aurez pas atteint le dernier enregistrement du tableau. Inclure des garanties que les objets liés seront là sur le * premier * enregistrement que vous itérez. –

+3

"Quelle instruction SQL inclut une profondeur illimitée dans une hiérarchie auto-référencée?" -> Expressions de table communes dans T-SQL –

1

Ok, vous pourriez envisager d'utiliser la méthode Load.

if (!category.Children.IsLoaded) 
     category.Children.Load(); 

Bien sûr, l'entité de catégorie doit être suivie par ObjectContext.

Il y a une meilleure explication ici how-does-entity-framework-work-with-recursive-hierarchies-include-seems-not-to.

+0

Je connais cette méthode (elle va générer des hundrets de requêtes T-SQL), mais aussi je la charge sans suivi, parce que je la sauvegarde dans le cache. Je cherche autre chose. Si je charge la table entière des catégories, j'ai chargé également des catégories de parents et d'enfants, mais les propriétés d'association ne sont pas chargées. Aussi j'ai la table connexe de CategoryType et je le charge pour chaque catégorie sans tenir compte de la même rangée ... –

+0

Ok, je n'ai pas vu que vous devez le mettre en cache. Hmm, je vais essayer de penser comment cela pourrait être résolu. –

0

Une façon que je l'ai utilisé pour mettre en œuvre que si j'ai plusieurs entités je veux que tous les enfants dans le tableau d'auto-référencement est d'utiliser cte récursive et procédure stockée pour obtenir leur carte d'identité en utilisant l'entité FrameWork: Here is the code using Entity Framework and code first approach

Questions connexes