C#中Linq多分组连接问题:关联Section、Question与Messages
解决Section→Question→Messages的多层GroupJoin嵌套问题
嘿,我看了你的代码,发现两个核心问题:一个是你把两次GroupJoin分开执行了,没法形成Section→Question→Messages的三层关联;另一个是第二个GroupJoin里的变量拼写和逻辑没嵌套对,导致出现了错误。
先说说错误原因
你写的第二个GroupJoin里,变量名拼写成了groupJoisn(多了个s),而且更关键的是,你只是单独对Question和Messages做了分组,没有把这个关联嵌套到Section的分组结果里。另外,虽然QuestionID不存在的错误看起来是属性找不到,但其实是你没有在Section的分组逻辑里把Messages关联进去,导致没法形成完整的层级。
正确的解决方案:嵌套GroupJoin
要实现Section包含Question,Question包含Messages的层级,你需要在第一次GroupJoin(Section和Question)的结果选择器里,对每个Question再执行一次GroupJoin关联Messages。这样就能把三层结构一次性构建出来。
下面是修正后的完整代码:
using System; using System.Linq; using System.Collections.Generic; public class Program { public static void Main() { // 初始化数据集合 IList<Question> QuestionList = new List<Question>() { new Question() { QuestionID = 1, QuestionName = "q1", SectionID = 1 }, new Question() { QuestionID = 2, QuestionName = "q2", SectionID = 1 }, new Question() { QuestionID = 3, QuestionName = "q3", SectionID = 2 }, new Question() { QuestionID = 4, QuestionName = "q4" , SectionID = 2 }, new Question() { QuestionID = 5, QuestionName = "q5" } // 这个Question没有关联Section和Messages }; IList<Section> SectionList = new List<Section>() { new Section(){ SectionID = 1, SectionName="Section 1"}, new Section(){ SectionID = 2, SectionName="Section 2"}, new Section(){ SectionID = 3, SectionName="Section 3"} // 这个Section没有关联Question }; IList<Messages> MessagesList = new List<Messages>() { new Messages(){ MessagesID = 1, MessagesName="Message 1",QuestionID=1}, new Messages(){ MessagesID = 2, MessagesName="Message 2",QuestionID=1}, new Messages(){ MessagesID = 3, MessagesName="Message 3",QuestionID=2} }; // 嵌套GroupJoin:先关联Section和Question,再在每个Question下关联Messages var sectionWithQuestionsAndMessages = SectionList.GroupJoin( QuestionList, section => section.SectionID, question => question.SectionID, (section, questionsInSection) => new { SectionName = section.SectionName, // 对当前Section下的每个Question,关联对应的Messages Questions = questionsInSection.GroupJoin( MessagesList, question => question.QuestionID, message => message.QuestionID, (question, messagesInQuestion) => new { QuestionName = question.QuestionName, Messages = messagesInQuestion } ) } ); // 遍历输出完整的层级结构 foreach (var section in sectionWithQuestionsAndMessages) { Console.WriteLine($"* {section.SectionName}"); foreach (var question in section.Questions) { Console.WriteLine($" - {question.QuestionName}"); foreach (var message in question.Messages) { Console.WriteLine($" · {message.MessagesName}"); } } } } } public class Question{ public int QuestionID { get; set; } public string QuestionName { get; set; } public int SectionID { get; set; } } public class Messages{ public int MessagesID { get; set; } public string MessagesName { get; set; } public int QuestionID { get; set; } } public class Section{ public int SectionID { get; set; } public string SectionName { get; set; } }
代码说明
- 嵌套GroupJoin:在Section和Question的分组结果中,我们对每个
questionsInSection集合再次执行GroupJoin,关联对应的Messages集合,这样就形成了Section→Question→Messages的三层结构。 - 空数据处理:对于没有关联Question的Section(比如Section 3),或者没有关联Messages的Question(比如q3、q4、q5),GroupJoin会返回空集合,不会抛出错误。
- 清晰的层级输出:使用带缩进的符号输出,让层级关系一目了然。
运行这段代码后,你会得到如下输出:
* Section 1 - q1 · Message 1 · Message 2 - q2 · Message 3 * Section 2 - q3 - q4 * Section 3
内容的提问来源于stack exchange,提问作者Tom Cruise
相关产品推荐
相关产品推荐

