Linq-to-Sql: recursively get children(Linq-to-Sql:递归获取子项)
问题描述
I have a Comment table which has a CommentID and a ParentCommentID. I am trying to get a list of all children of the Comment. This is what I have so far, I haven't tested it yet.
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 questions:
- Is there any obvious way to improve this? (Besides maybe creating a view in sql with a CTE.)
- How come I can't yield a
IEnumerable <Comment>to an IEnumerable<Comment>, onlyCommentitself? - Is there anyway to use SelectMany in this situation?
I'd probably use either a UDF/CTE, or (for very deep structures) a stored procedure that does the same manually.
Note that if you can change the schema, you can pre-index such recursive structures into an indexed/ranged tree that lets you do a single BETWEEN query - but the maintenance of the tree is expensive (i.e. query becomes cheap, but insert/update/delete become expensive, or you need a delayed scheduled task).
Re 2 - you can only yield the type specified in the enumeration (the T in IEnumerable<T> / IEnumerator<T>).
You could yield an IEnumerable<Comment> if the method returned IEnumerable<IEnumerable<Comment>> - does that make sense?
Improvements:
- perhaps a udf (to keep composability, rather than a stored procedure) that uses the CTE recursion approach
- use
using, sinceDataContextisIDisposable...
so:
using(var db = new MyDataContext() ) { /* existing code */ }
- LoadWith is worth a try, but I'm not sure I'd be hopeful...
- the list of searched ids is risky as a field - I guess you're OK as long as you don't call it twice... personally, I'd use an argument on a private backing method... (i.e. pass the list between recursive calls, but not on the public API)
这篇关于Linq-to-Sql:递归获取子项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:Linq-to-Sql:递归获取子项
基础教程推荐
- .NET SerialPort DataReceived 事件未触发 2022-01-01
- 当值可以是对象或空数组时反序列化 JSON 2022-01-01
- WPF 模态进度窗口 2022-01-01
- C# 从 List<List<int>> 中删除重 2022-01-01
- 如何使用 .Net 检查 Active Directory 服务器是否已启动并正在运行? 2022-01-01
- Azure Functions:CosmosDBTrigger 未在 Visual Studio 中触发 2022-01-01
- 我应该在后面的代码中直接使用 Linq To SQL 还是使 2022-01-01
- 如果有人提交恶意软件Nuget包怎么办? 2022-01-01
- 禁止输入少量字符,例如'<'、'&a 2022-01-01
- Moq It.Is<>不匹配 2022-01-01
