Explication des raisons pour lesquelles cette question diffère: EF - multiple permet de charger rapidement des données hiérarchiques. Mauvaise pratique?
Dans le projet actuel (une API Web .NET principale), j'essaie de charger une hiérarchie à partir d'une table d'auto-référencement.
Après avoir beaucoup cherché sur Google, j'ai été surpris qu'une telle tâche (que je pensais être triviale) ne semble pas être anodine.
Eh bien, j'ai cette table pour former ma hiérarchie:
CREATE TABLE [dbo].[Hierarchy] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Parent_Id] INT NULL,
[Name] NVARCHAR (50) NOT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_Hierarchy_Hierarchy] FOREIGN KEY ([Parent_Id]) REFERENCES [dbo].[Hierarchy] ([Id])
);
Dans l’API Web, j’essaie de renvoyer la hiérarchie complète. Une chose peut-être spéciale (qui pourrait aider) est le fait que je veuille charger le tableau complet.
Je sais aussi que je pourrais utiliser le chargement rapide et la propriété de navigation (Parent et InverseParent pour les enfants)
_dbContext.Hierarchy.Include(h => h.InverseParent).ThenInclude(h => h.InverseParent)...
Le problème, c'est que cela chargerait une profondeur codée en dur (par exemple, six niveaux si j'utilise 1 Include () et 5 ThenInclude ()), mais ma hiérarchie a une profondeur flexible.
Quelqu'un peut-il m'aider en me donnant du code sur la manière de charger la table complète (par exemple, en mémoire dans un scénario optimal avec 1 appel de base de données), puis d'obliger la méthode à renvoyer la hiérarchie complète?
En fait, charger la hiérarchie entière est assez facile grâce à ce qu'on appelle EF (Core) relation de correction.
Disons que nous avons le modèle suivant:
public class Hierarchy
{
public int Id { get; set; }
public string Name { get; set; }
public Hierarchy Parent { get; set; }
public ICollection<Hierarchy> Children { get; set; }
}
Puis le code suivant
var hierarchy = db.Hierarchy.Include(e => e.Children).ToList();
chargera toute la hiérarchie avec les propriétés Parent
et Children
correctement remplies.
Le problème décrit dans les publications référencées survient lorsque vous ne devez charger qu'une partie de la hiérarchie, ce qui est difficile en raison de l'absence de support CTE semblable à celui de LINQ.
J'ai construit une procédure stockée pour obtenir tous les enfants de tous les niveaux en utilisant un cte récursif Procédure stockée pour obtenir tous les ids des enfants de tout niveau de table d'auto-référencement utilisant Entity Framework et un cte récursif