SQLとEntityFramework(ADO.NET Entity Mapping)の両方でこの再帰を使用するのは初めてです。私はComments
テーブルがあり、テーブルに列が含まれているコメント管理に取り組んでいますNewsID, CommentID, ParentCommentID, IndentLevel, CreatedTime
。
以下に示すように、特定のニュースアイテムのコメントのリストを取得しようとしています。ここでは、すべてのコメントが親の下の子と作成された時間に従って配置されています。
CommentID | time | ParentCommentID
Guid1 | t1 | null
Guid4 | t4 | Guid1
Guid2 | t2 | null
Guid3 | t3 | Guid2
子と親の関係、次に作成された時間を優先する必要があります。
私がこれまでに学んだことは(インターネットリソースと以前のstackoverflow Q / Aから)
- 示されているように、これらの再帰クエリは低速です。EntityFrameworkを使用してこれを行うのはさらに遅くなります。しかし、それは達成できます。
- したがって、SQL Serverでストアドプロシージャを作成し、機能インポートを使用して呼び出すことで実行できます。もう1つは、EntityFrameworkでLinqを使用することです。
- SQL Serverでは、この形式で使用されます
SQL:
WITH cte_name ( column_name [,...n] )
AS
(
CTE_query_definition –- Anchor member is defined.
UNION ALL
CTE_query_definition –- Recursive member is defined referencing cte_name.
)
-- Statement using the CTE
SELECT *
FROM cte_name
- しかし、これを試す前に、Linqを試してみたいと思います。
このために私は私が考えを持っているこのリンクを参照しています: https ://stackoverflow.com/a/6225373/892788
しかし、私はコードを理解しようとしましたが、無駄でした。Entity Frameworkで再帰CTEを作成する方法について、より適切で詳細な説明を教えてもらえますか?
private IEnumerable<NewsComment> ArrangeComments(IEnumerable<NewsComment> commentsList, string parentNewsComntID, int level)
{
Guid parentNewsCommentID;
if (parentNewsComntID != null)
{
parentNewsCommentID = new Guid(parentNewsComntID);
}
else
parentNewsCommentID = Guid.Empty;
return commentsList.Where(x => x.ParentCommentID == parentNewsCommentID).SelectMany(x => new[] { x }.Concat(ArrangeComments(commentsList, x.NewsCommentID.ToString(), level + 1));
}
そして、私はこれを以下のようにメソッド内で使用しています:
return ArrangeComments(commentList,null , 0);
私はそれらを試しましたが、どこにも行かないようです。SQL再帰についての説明はありますが、Linqの例は少なく、慣れていないためにあいまいです。誰かがLinqでのこのCTE再帰を理解するのを手伝ってくれませんか?
前もって感謝します