Linq challenge: converting this piece of code from method chain to standard Linq

核能气质少年 提交于 2020-01-05 04:09:29

问题


The challenge is about converting from method chain to standard linq a piece of code full of group by.

The context

To fully understand the topic here you can read the original question (with class definitions, sample data and so on): Linq: rebuild hierarchical data from the flattened list

Thanks to @Akash Kava, I've found the solution to my problem.

Chain method formulation

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

But, for sake of knowledge, I've tried to convert the method chain to the standard Linq formulation but something is wrong.

What happens is similar to this..

My attempt to convert it to Linq standard syntax

var antiflatten = flattenedList
    .GroupBy(x => x.IDMacroTab)
    .Select(grouping => new MacroTab
    {
        IDMacroTab = grouping.Key,
        Tabs = (from t in grouping
                group grouping by t.IDTab
                into group_tx
                select new Tab
                {
                    IDTab = group_tx.Key,
                    Slots = (from s in group_tx
                    from s1 in s    
                    select new Slot
                    {
                        IDSlot = s1.IDSlot
                    }).ToList()
                }).ToList()
    });

The result in LinqPad

The classes and the sample data on NetFiddle:

https://dotnetfiddle.net/8mF1qI


回答1:


This challenge helped me to understand what exactly returns a Linq Group By (and how prolix is the Linq syntax with Group By).

As LinqPad clearly shows a Group By returns a List of Groups. Group is a very simple class which has just one property: a Key

As this answer states, from definition of IGrouping (IGrouping<out TKey, out TElement> : IEnumerable<TElement>, IEnumerable) the only way to access to the content of the subgroups is to iterate through elements (a foreach, another group by, a select, ecc).

Here is shown the Linq syntax formulation of the method chain.

And here is the source code on Fiddle

But let's go on trying to see another solution:

What we usually do in SQL when we do a Group By is to list all the columns but the one which have been grouped. With Linq is different.. it still returns ALL the columns.

In this example we started with a dataset with 3 'columns' {IDMacroTab, IDTab, IDSlot}. We grouped for the first column, but Linq would return the whole dataset, unless we explicitly tell him..



来源:https://stackoverflow.com/questions/52757509/linq-challenge-converting-this-piece-of-code-from-method-chain-to-standard-linq

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!