Pergunta

Eu tenho um auto tabela referencial, que tem ID, ParentID (anulável).

Assim, a tabela contém muitos nós, cada nó poderia ser a raiz na hierarquia (progenitor é nula), ou qualquer nível da hierarquia (progenitor existir noutro local na tabela).

Dado um nó de partida arbitrário, existe uma consulta linq elegante que irá retornar todas as crianças da hierarquia por esse nó?

Graças.

Foi útil?

Solução

Se você quiser selecionar todas as crianças diretos de um nó, uma consulta simples como o seguinte deve fazer o trabalho:

from item in table
where item.ID == parentID;
select item

Se você quiser selecionar todos os descendentes de um nó, isso não é possível com o LINQ, porque exige recursão ou uma pilha que LINQ (e SQL) não fornece.

Veja também:

Outras dicas

Aqui está um rápido eu só escrevi:

class MyTable
{
    public int Id { get; set; }
    public int? ParentId { get; set; }
    public MyTable(int id, int? parentId) { this.Id = id; this.ParentId = parentId; }
}

List<MyTable> allTables = new List<MyTable> {
    new MyTable(0, null), 
    new MyTable(1, 0),
    new MyTable(2, 1)
};

Func<int, IEnumerable<MyTable>> f = null;
f = (id) =>
{
    IEnumerable<MyTable> table = allTables.Where(t => t.Id == id);

    if (allTables
        .Where(t => t.ParentId.HasValue && t.ParentId.Value == table
            .First().Id).Count() != 0)
        return table
            .Union(f(
            allTables.Where(t => t.ParentId.HasValue && t.ParentId.Value == table
                .First().Id).First().Id));
    else return table;

};

Mas eu acredito que é possível fazer usando SQL com uma União ALL.

Eu sei que este é um post antigo, mas você deve verificar se esta extensão:

http://www.scip.be/index.php?Page=ArticlesNET23

Eu tenho usado ele e ele está trabalhando muito.

Basicamente, eu estou indo com algo assim como discutido no link para que você proivded.

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

CTEs são provavelmente a melhor solução, mas eu gostaria de manter as coisas todas no mesmo nível para agora.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top