Pergunta

Eu tenho uma auto-referência a tabela de Categorias.Cada Categoria tem uma CategoryID ParentCategoryID, Nomedacategoria etc.E cada categoria pode ter qualquer número de sub-categorias, e cada uma dessas sub-categorias podem ter qualquer número de sub-categorias, e o e e assim por diante.Então, basicamente, a árvore pode ser X níveis de profundidade.

Em seguida, os Produtos são associados a folha (sub) Categorias.Existe uma maneira de obter todos os Produtos para uma determinada Categoria (o que seria todos os produtos associados a todas as suas folhas descendentes) usando LINQ to SQL?

Este se sente como uma recursiva do problema.É melhor usado um Procedimento Armazenado em vez disso?

Foi útil?

Solução

Eu não acho que o linq para sql, tem uma boa resposta para esse problema.Desde que você está usando o sql server 2005, você pode usar CTEs para fazer consultas hierárquicas.Um procedimento armazenado ou uma linha de consulta (usando o DataContext.ExecuteQuery) irá fazer o truque.

Outras dicas

Bem, aqui está uma terrível correu implementação usando LINQ.Não use isso :-)

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

A performance abordagem é criar um inserir/modificar/excluir gatilho que mantém um modo totalmente diferente de tabela que contém o nó ancestral pares para todos os antepassados de todos nós.Desta forma, a pesquisa é O(N).

Para usá-lo para obter todos os produtos pertencentes a um nó e todos os seus descendentes, você pode apenas selecionar todos os nós categoria que tem o seu nó de destino como um ancestral.Após isso, basta selecionar qualquer um dos produtos pertencentes a qualquer uma destas categorias.

A maneira de eu lidar com isso é usando alguns métodos de extensão (filtros).Eu tenho escrito alguns códigos de exemplo a partir de um projeto que implementou isto.Procurar especificamente nas linhas onde eu estou preencher um ParentPartner objeto e um SubPartners Lista.

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;
        }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top