Domanda

Ho una tabella Categorie autoreferenziale.Ogni categoria ha un CategoryID, ParentCategoryID, CategoryName, ecc.E ogni categoria può avere un numero qualsiasi di sottocategorie, e ciascuna di queste sottocategorie può avere un numero qualsiasi di sottocategorie, e così via.Quindi in pratica l'albero può essere profondo X livelli.

Quindi i Prodotti vengono associati alle (sotto)categorie fogliari.Esiste un modo per ottenere tutti i prodotti per una determinata categoria (che sarebbero tutti i prodotti associati a tutti i suoi discendenti foglia) utilizzando LINQ to SQL?

Sembra un problema ricorsivo.È meglio utilizzare invece una Stored Procedure?

È stato utile?

Soluzione

Non penso che linq-to-sql abbia una buona risposta a questo problema.Poiché stai utilizzando SQL Server 2005, puoi utilizzare CTE per eseguire query gerarchiche.Una procedura memorizzata o una query in linea (utilizzando DataContext.ExecuteQuery) basterà.

Altri suggerimenti

Bene, ecco una terribile implementazione affrettata utilizzando LINQ.Non usarlo :-)

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

L'approccio performante consiste nel creare un trigger di inserimento/modifica/eliminazione che mantenga una tabella completamente diversa che contiene coppie nodo-antenato per tutti gli antenati di tutti i nodi.In questo modo, la ricerca è O(N).

Per usarlo per ottenere tutti i prodotti appartenenti a un nodo e tutti i suoi discendenti, puoi semplicemente selezionare tutti i nodi di categoria che hanno il tuo nodo target come antenato.Successivamente, seleziona semplicemente i prodotti appartenenti a una di queste categorie.

Il modo in cui lo gestisco è utilizzando alcuni metodi di estensione (filtri).Ho scritto del codice di esempio da un progetto su cui ho implementato questo.Guarda in particolare le righe in cui sto compilando un oggetto ParentPartner e un elenco di SubPartners.

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;
        }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top