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