Question

J'ai une table Catégories auto-référencée.Chaque catégorie a un CategoryID, un ParentCategoryID, un CategoryName, etc.Et chaque catégorie peut avoir n'importe quel nombre de sous-catégories, et chacune de ces sous-catégories peut avoir n'importe quel nombre de sous-catégories, et ainsi de suite.Donc, fondamentalement, l’arbre peut avoir une profondeur de X niveaux.

Ensuite, les produits sont associés aux (sous) catégories feuilles.Existe-t-il un moyen d'obtenir tous les produits d'une catégorie donnée (qui seraient tous les produits associés à tous ses descendants feuilles) à l'aide de LINQ to SQL ?

Cela ressemble à un problème récursif.Vaut-il mieux utiliser une procédure stockée à la place ?

Était-ce utile?

La solution

Je ne pense pas que Linq-to-sql ait une bonne réponse à ce problème.Puisque vous utilisez SQL Server 2005, vous pouvez utiliser les CTE pour effectuer des requêtes hiérarchiques.Une procédure stockée ou une requête en ligne (utilisant DataContext.ExecuteQuery) fera l'affaire.

Autres conseils

Eh bien, voici une implémentation terriblement précipitée utilisant LINQ.N'utilisez pas ça :-)

public IQueryable GetCategories(Category parent)
{
    var cats = (parent.Categories);
    foreach (Category c in cats )
    {
        cats  = cats .Concat(GetCategories(c));
    }
    return a;
}

L'approche performante consiste à créer un déclencheur d'insertion/modification/suppression qui maintient une table entièrement différente contenant des paires nœud-ancêtre pour tous les ancêtres de tous les nœuds.De cette façon, la recherche est O(N).

Pour l'utiliser pour obtenir tous les produits appartenant à un nœud et tous ses descendants, vous pouvez simplement sélectionner tous les nœuds de catégorie qui ont votre nœud cible comme ancêtre.Après cela, il vous suffit de sélectionner tous les produits appartenant à l’une de ces catégories.

La façon dont je gère cela consiste à utiliser certaines méthodes d'extension (filtres).J'ai rédigé un exemple de code à partir d'un projet sur lequel je l'ai implémenté.Regardez spécifiquement les lignes où je remplis un objet ParentPartner et une liste de sous-partenaires.

public IQueryable<Partner> GetPartners()
        {
            return from p in db.Partners
                   select new Partner
                   {
                       PartnerId = p.PartnerId,
                       CompanyName = p.CompanyName,
                       Address1 = p.Address1,
                       Address2 = p.Address2,
                       Website = p.Website,
                       City = p.City,
                       State = p.State,
                       County = p.County,
                       Country = p.Country,
                       Zip = p.Zip,
                       ParentPartner = GetPartners().WithPartnerId(p.ParentPartnerId).ToList().SingleOrDefault(),
                       SubPartners = GetPartners().WithParentPartnerId(p.PartnerId).ToList()
                   };
        }


public static IQueryable<Partner> WithPartnerId(this IQueryable<Partner> qry, int? partnerId)
        {
            return from t in qry
                   where t.PartnerId == partnerId
                   select t;
        }

public static IQueryable<Partner> WithParentPartnerId(this IQueryable<Partner> qry, int? parentPartnerId)
        {
            return from p in qry
                   where p.ParentPartner.PartnerId == parentPartnerId
                   select p;
        }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top