Home > Software design >  LINQ Group By Year to Form a Tree View
LINQ Group By Year to Form a Tree View

Time:06-30

I am trying to create a tree view that would essentially break down like so:

- Year
  - Month
    - Related Item

So we might have the Year 2022, that has several related items within the several months.

I have created the following model:

public class TreeYear
{
    public string NodeYear { get; set; }
    public DateTime CreatedDateTime { get; set; }
    public List<TreeMonth> Months { get; set; }

}

public class TreeMonth
{
    public int MonthID { get; set; }
    public string MonthName { get; set; }
    public quoteSummary QuoteSummary{ get; set; }
}

I have written some code in my controller which currently returns every item like so:

  var allQuotes = QuoteSummary.ToList();

  var tree = new TreeYear();
  foreach (var quote in allQuotes)
  {
      tree.NodeYear= quote.CreatedTime.Year.ToString();
      tree.CreatedDateTime = quote.CreatedTime;
      tree.Months = new List<TreeMonth>()
      {
        new TreeMonth() {
        MonthID = quote.CreatedTime.Month,
        MonthName = getAbbreviatedName(quote.CreatedTime.Month),
        QuoteSummary = quote
        }
       };
  }

enter image description here

But obviously over here you can see that it has all 41 records of which none are grouped up by year.

I thought maybe I could write some linq something like but at the moment incorrect:

var groups = TheResponse.Details
             .GroupBy(
                  d => Int32.Parse(d.NodeYear),
                   (key, g) => g.GroupBy(
                       d => d.Months.Select(x => x.MonthID)),
                         (key2, g2) => g2.GroupBy(d => d.CreatedDateTime)
                        )
                    );

Or would I need to change the model for this idea to work?

CodePudding user response:

If I understood your question correctly, then you need to flatten the inner list and then group by months again.

var groups = TheResponse.Details
                        .GroupBy(d => Int32.Parse(d.NodeYear))
                        .Select(d => new 
                               {
                                   Year = d.Key,
                                   MonthObj = d.SelectMany(m => m.Months)
                                               .GroupBy(m => m.MonthID)
                                               .Select(x => new 
                                                      {
                                                          MonthID = x.Key,
                                                          RelatedItem = x.ToList()
                                                      })
                               });

I have simplified it by using anonymous types, but you can obviously tweek it based on your resp. Model.

  • Related