convert foreach to lambda expression in C#

c# entity-framework-6 lambda

Question

I'm new to using lambda notation so please correct my understanding if I'm wrong. Is it possible to rewrite the a for each loop in one statement using lambda? I having the following:

Model

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;
}
1
1
2/13/2017 2:08:19 PM

Accepted Answer

There was a previous answer that someone posted that got deleted... This solutions accomplishes what I was trying to do in a single statement.

sections.ForEach(s => { s.Questions = questions.Where(q => q.SectionID == s.SectionID).ToList(); });
0
10/14/2016 7:54:15 PM

Popular Answer

I think you are using Entity Framework and if so set the Navigation Properties and just:

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

If this is a one-to-many relationship check: Configure One-to-Many Relationship

If you are not using Entity Framework then GroupJoin the two tables and project a new 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
              });

If for some reason you do not want to use the Navigation Properties, nor project a new Section, your data is big and ypu want to use the foreach then do it this way:

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;
    }
}

The reason I made this foreach more complex is so the questions is stored in a dictionary where the key is the SectionID. This way the complexity is of o(n) and not o(n)2 (as when using foreach + Where)

But again.. as you see by all the if in the explanation.. Best option without doubt is just to use navigation properties



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow