質問

ID、ParentID(nullable)を持つ自己参照テーブルがあります。

したがって、テーブルには多くのノードが含まれ、各ノードは階層のルート(親はnull)、または階層の任意のレベル(親はテーブルのどこかに存在します)になります。

任意の開始ノードを指定すると、そのノードから階層のすべての子を返すエレガントなlinqクエリがありますか?

ありがとう。

役に立ちましたか?

解決

ノードのすべての直接の子を選択する場合は、次のような簡単なクエリを実行する必要があります。

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

ノードのすべての子孫を選択する場合、LINQ(およびSQL)が提供しない再帰またはスタックが必要なため、これはLINQでは不可能です。

参照:

他のヒント

これは私が書いた簡単なものです:

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;

};

しかし、Union ALLでSQLを使用することは可能だと思います。

これは古い投稿ですが、この拡張機能を確認する必要があります:

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

私はそれを使用してきましたが、うまく機能しています。

基本的には、提供したSOリンクで説明したように、このようなものを使用します。

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

CTEはおそらく最良のソリューションですが、現時点ではすべてを同じ階層に維持したいと思います。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top