Pregunta

Tengo una tabla autorreferencial, que tiene ID, ParentID (anulable).

Entonces, la tabla contiene muchos nodos, cada nodo podría ser la raíz en la jerarquía (el padre es nulo) o cualquier nivel de la jerarquía (el padre existe en otra parte de la tabla).

Dado un nodo inicial arbitrario, ¿hay una consulta linq elegante que devolverá a todos los hijos de la jerarquía de ese nodo?

Gracias.

¿Fue útil?

Solución

Si desea seleccionar todos los hijos directos de un nodo, una consulta simple como la siguiente debería hacer el trabajo:

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

Si desea seleccionar todos los descendientes de un nodo, esto no es posible con LINQ, porque requiere recursividad o una pila que LINQ (y SQL) no proporciona.

Ver también:

Otros consejos

Aquí hay uno rápido que acabo de escribir:

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;

};

Pero creo que es posible hacerlo usando SQL con Union ALL.

Sé que esta es una publicación anterior, pero debería consultar esta extensión:

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

Lo he estado usando y está funcionando muy bien.

Básicamente voy con algo como esto como se discutió en el enlace SO que proporcionó.

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

Los CTE son probablemente la mejor solución, pero por ahora me gustaría mantener todo en el mismo nivel.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top