ID、ParentID(ヌル可能)を持つ自己参照テーブルがあります。
そのため、テーブルには多くのノードが含まれ、各ノードは階層のルート (親が null) になるか、階層の任意のレベル (親がテーブルの別の場所に存在する) になる可能性があります。
任意の開始ノードが与えられた場合、そのノードから階層のすべての子を返すエレガントな linq クエリはありますか?
ありがとう。
ID、ParentID(ヌル可能)を持つ自己参照テーブルがあります。
そのため、テーブルには多くのノードが含まれ、各ノードは階層のルート (親が null) になるか、階層の任意のレベル (親がテーブルの別の場所に存在する) になる可能性があります。
任意の開始ノードが与えられた場合、そのノードから階層のすべての子を返すエレガントな 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 を使用することは可能だと思います。
ノードの直接の子をすべて選択したい場合は、次のような単純なクエリを実行する必要があります。
from item in table
where item.ID == parentID;
select item
ノードのすべての子孫を選択する場合、LINQ (および SQL) が提供しない再帰またはスタックが必要なため、これは LINQ では不可能です。
以下も参照してください。
これは古い投稿であることは承知していますが、次の拡張機能を確認してください。
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 はおそらく最良のソリューションですが、今のところすべてを同じ層に保ちたいと考えています。