1

Disclaimer: I've been fighting against this problem since 2 days (I've read a lot of similar questions on SO).. so be patient, I'm missing something about the Group By with Linq and asking for help.

The Class Structure

enter image description here enter image description here

Populating the sample data

I have a list of Macrotab. Each Macrotab object contains a list of Tab. Each Tab object inside with Slot inside.

List<MacroTab> hierarchaldata = CreateHierarchaldata();

*For keeping the question easy to read I've moved the CreateHierarchaldata, which populates a set of sample data, to .NetFiddle: https://dotnetfiddle.net/8mF1qI

Flattening

The following lines flattens this structure using Linq:

var flattenedList = (from macroTab in hierarchaldata
            from tab in macroTab.Tabs
            from slot in tab.Slots
            select new {macroTab.IDMacroTab, tab.IDTab, slot.IDSlot}).ToList();

Aggregate the data back to hierarchy

I've tried to get back to the original list using the the Linq Group By. This was my objective: to Aggregate the data for the Id of the MacroTab, Tabs and Slots and recreate the original list, but it doesn't work as expected**:

var antiflatten = from macrotab in flattenedList
            group macrotab by new {macrotab.IDMacroTab}
            into macrotabs
            let macrotabFirst = macrotabs.First()
            select new MacroTab
            {
                IDMacroTab = macrotabFirst.IDMacroTab,
                Tabs = (from macrotab in macrotabs
                    group macrotabs by new {macrotab.IDTab}
                    into tabs
                    let tabFirst = tabs.First()
                    select new Tab(){ HelperClass = tabFirst}).ToList()
            };

**The property HelperClass is just for debugging purpose, I hope it's not confusing, I've left it to explain the Visual Studio debugger's screenshot

enter image description here

Try it on Fiddler

Revious
  • 7,816
  • 31
  • 98
  • 147

1 Answers1

1
    var macroTabs = flattenedList
        .GroupBy(x => x.IDMacroTab)
        .Select((x) => new MacroTab
        {
            IDMacroTab = x.Key,
            Tabs = x.GroupBy(t => t.IDTab)
                    .Select(tx => new Tab {
                        IDTab = tx.Key,
                        Slots = tx.Select(s => new Slot {
                           IDSlot = s.IDSlot
                     }).ToList()
            }).ToList()
        }).ToList();
Akash Kava
  • 39,066
  • 20
  • 121
  • 167
  • I tried to convert the method chain to the normal Linq sintax but I failed again... have you got some suggestion? – Revious Oct 11 '18 at 09:58
  • 1
    Honestly, I tried too, I feel more comfortable in method syntax like above, where we know how code flows. – Akash Kava Oct 11 '18 at 10:04
  • I think your solution is really more clear and readable, but for the sake of knowledge I've opened a kind of Linq challenge here: https://stackoverflow.com/questions/52757509/linq-converting-this-piece-of-code-from-method-chain-to-standard-linq – Revious Oct 11 '18 at 10:13