0

I have three Models something like this:

public class Section
{
  public string Id {get; set;}

  public SubSection[] SubSections {get; set;}

  public Item[] Items {get; set;}
}

public class SubSection
{
  public string Id {get; set;}

  public string sectionId {get; set;}

  public Item[] Items {get; set;}
}

public class Item
{
  public string Id {get; set;}

  public string sectionId {get; set;}
}

Now when I get the result back I get back list of Sections and Items and would like to merge these two lists to put it into the above Models.

Everything is connected with Section Id; determining where the item goes in SubSection or directly under section and the subsections go under section array.

Is there a good way to do this using Linq?

Example:

Item { id = "123", sectionId = "456"}
Item {id = "234", sectionId = "786"}

SubSection {id = "211", sectionId = "786", Items = null}
SubSection {id = "210", sectionId = 456", Items[] = new Item() {"123"}}

Section {id = 786, subsections[] = null, items[] =  new Item() {"234" }}
Section {id = 456, subsection[] = new SubSection { id = 210}, items = null}
2
  • "Now when I get the result back"... How do you get it? Is it through a Web API? ORM call? In-memory collection? Commented Feb 9, 2016 at 20:22
  • Yes, Its from the Web API and it's returned as IList<Item> itemList and IList<Section> section List --> Internally even SubSection is treated as Section... Commented Feb 9, 2016 at 20:27

2 Answers 2

1

LINQ is good at reading and transforming, but not at modifying items where they stand. It's doable (a right way and a "wrong" way), but unless you specifically need that, I'll focus on what you're asking here.

List<SectionWithoutCollections> sections;
List<SubSectionWithoutCollections> subSections;
List<Item> items;

var subSectionsWithItems = subSections
    .GroupJoin(items, a => a.Id, b => b.SectionId, (a,b) => new SubSection
               {
                   Id = a.Id,
                   SectionId = a.SectionId,
                   Items = b.ToArray()
               });

var sectionsWithItems = sections
    .GroupJoin(subSectionsWithItems, a => a.Id, b => b.SectionId, (a,b) => new { Section = a, SubSections = b })
    .GroupJoin(items, a => a.Section.Id, b => b.SectionId, (a,b) => new Section
               {
                   Id = a.Section.Id,
                   Items = b.ToArray(),
                   SubSections = a.SubSections.ToArray()
               });

I did this in two steps, but you could do it in one, if readability didn't matter (which is always does).

It's pretty straight-forward once you know the methods, but basically I put all the subsections and items together, then I put all the sections and subsections together, then I put all the sections-and-subsections and items together.

Just note that any orphaned items or subsections (i.e. those for which no section or subsection with SectionId exist) will be thrown out. But that's bad relational anyway, so that's acceptable, as far as I know.

Sign up to request clarification or add additional context in comments.

Comments

0
var sections = new List<Section>();
        var subSections = new List<SubSection>();
        var items = new List<Item>();

        var itemSections = from s in sections
                           let i = items.Where(j => j.sectionId == s.Id).DefaultIfEmpty().ToArray()
                           let ss = subSections.Where(j => j.sectionId == s.Id).DefaultIfEmpty().ToArray()

                           select new Section
                           {
                               Id = s.Id,
                               SubSections = ss,
                               Items = i
                           };

This should work, haven't tested. Not sure what you mean by Merge tho

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.