将foreach转换为C#中的lambda表达式

时间:2016-10-14 18:37:08

标签: c# lambda entity-framework-6

我是使用lambda表示法的新手,所以如果我错了,请纠正我的理解。是否可以使用lambda在一个语句中为每个循环重写a?我有以下内容:

模型

public partial class Section
{
    public int SectionID { get; set; }
    public List<Question> questions { get; set; }
    //...
}

public partial class Question
{
    public int QuestionID { get; set; }
    public int SectionID { get; set; }
    //...
}

FOREACH

List<Section> sections = db.getSections.ToList();
List<Question> questions = db.getQuestions.ToList();

foreach (var section in sections)
{
    List<Question> questionsInSection = new List<Question>();
    foreach (var question in questions)
    {
        if(section.SectionID == question.SectionID)
            questionsInSection.Add(question);
    }
    section.Questions = questionsInSection;
}

4 个答案:

答案 0 :(得分:1)

如果导航属性不是一个选项,并且您不想创建每个Section的新实例并逐个复制它的属性,您仍然可以使用LINQ替换内部foreach并保留外部foreach作为它是:

List<Section> sections = db.getSections.ToList();
List<Question> questions = db.getQuestions.ToList();
foreach (var section in sections)
{
    section.Questions = questions.Where(o => o.SectionID == section.SectionID).ToList();
}

答案 1 :(得分:1)

List<Section> sections = questions
                        .GroupBy(x=>x.SectionID)
                        .Select(x=>new Section(){SectionID=x.Key,questions=x.ToList()})
                        .ToList()

答案 2 :(得分:1)

我认为您正在使用Entity Framework,如果是这样,请设置Navigation Properties,只需:

var sections = db.getSections.Include(s => s.Questions)
                             .ToList();

如果这是一对多关系检查:Configure One-to-Many Relationship

如果您没有使用实体框架,那么GroupJoin这两个表并投影一个新的Section

var result = (from section in db.getSections
              join question in db.getQuestion 
              on section.SectionID == questions.SectionID into sectionQuestions
              select new Section
              {
                  Prop1 = section.Prop1,
                  Prop2 = section.prop2,
                  Questions = sectionQuestions
              });

如果出于某种原因你不想使用导航属性,也不想投射新的Section,那么你的数据很大,ypu想要使用foreach然后这样做:

var sections = db.getSections.ToList();
var questions = db.getQuestions.GroupBy(item => item.SectionID)
                               .ToDictionary(key => key.Key,
                                             value => value.Select(i => i).ToList());

foreach (var section in sections)
{
    List<Question> selectedQuestions;
    if (efficientQuestions.TryGetValue(section.SectionID, out selectedQuestions))
    {
        section.Questions = selectedQuestions;
    }
}

我使foreach更复杂的原因是问题存储在字典中,其中键是SectionID。这种方式的复杂性为o(n)而非o(n)2(与使用foreach + Where时相比)

但是再次..正如您在解释中所有if所看到的那样。毫无疑问,最佳选择只是使用导航属性

答案 3 :(得分:0)

之前的答案是有人发布了被删除的内容......此解决方案完成了我在一个声明中尝试做的事情。

sections.ForEach(s => { s.Questions = questions.Where(q => q.SectionID == s.SectionID).ToList(); });