5

CommentID と ParentCommentID を持つ Comment テーブルがあります。コメントのすべての子のリストを取得しようとしています。これは私がこれまでに持っているもので、まだテストしていません。

private List<int> searchedCommentIDs = new List<int>();
// searchedCommentIDs is a list of already yielded comments stored
// so that malformed data does not result in an infinite loop.
public IEnumerable<Comment> GetReplies(int commentID) {
    var db = new DataClassesDataContext();
    var replies = db.Comments
        .Where(c => c.ParentCommentID == commentID 
            && !searchedCommentIDs.Contains(commentID));
    foreach (Comment reply in replies) {
        searchedCommentIDs.Add(CommentID);
        yield return reply;
        // yield return GetReplies(reply.CommentID)); // type mis-match.
        foreach (Comment replyReply in GetReplies(reply.CommentID)) {
            yield return replyReply;
        }
    }
}

2 つの質問:

  1. これを改善する明白な方法はありますか?(CTEを使用してSQLでビューを作成することに加えて。)
  2. IEnumerable <Comment>aを IEnumerable<Comment>に譲ることができないのはCommentなぜですか?
  3. この状況で SelectMany を使用する方法はありますか?
4

1 に答える 1

4

おそらく、UDF/CTE を使用するか、(非常に深い構造の場合) 手動で同じことを行うストアド プロシージャを使用します。

スキーマを変更できる場合は、そのような再帰構造をインデックス付き/範囲指定されたツリーに事前にインデックス付けして、単一の BETWEEN クエリを実行できることに注意してください。ただし、ツリーのメンテナンスにはコストがかかります (つまり、クエリは安価になりますが、挿入/更新/delete のコストが高くなるか、スケジュールされたタスクの遅延が必要になります)。


yieldRe 2 -列挙型 ( /T内) で指定された型のみを使用できます。IEnumerable<T>IEnumerator<T>

メソッドが返さyieldれたIEnumerable<Comment> 場合は可能ですIEnumerable<IEnumerable<Comment>>-それは理にかなっていますか?

改良点:

  • おそらく、CTE再帰アプローチを使用するudf(ストアドプロシージャではなく、構成可能性を維持するため)
  • 使用usingDataContextなのでIDisposable...

それで:

using(var db = new MyDataContext() ) { /* existing code */ }
  • LoadWithは試してみる価値はありますが、期待できるかどうかはわかりません...
  • 検索された ID のリストはフィールドとして危険です - 2 回呼び出さない限り問題ないと思います... 個人的には、プライベート バッキング メソッドで引数を使用します... (つまり、再帰呼び出し間のリスト、ただしパブリック API ではありません)
于 2009-02-11T04:41:30.013 に答える