0

How to group by Properties and select other properties as lists using LINQ?

I'm bad at explaining it so here's an example:

Lets say I have a list of C# objects that can be represented in JSON like this:

[
    { "id":123, "name":"John", "carId":1, "carAge":3 },
    { "id":123, "name":"John", "carId":2, "carAge":4 },
    { "id":4, "name":"Mary", "carId":3, "carAge":3 },
    { "id":4, "name":"Mary", "carId":4, "carAge":3 },
    { "id":123, "name":"John", "carId":5, "carAge":3 }
]

Among all those objects only carId is unique.

I would like to group them by person details and join those details with connected car details.

The end result would look like this but as c# objects:

[
    {"id":123, "name":"John",
        [
            {"carId":1, "carAge":3},
            {"carId":2, "carAge":4},
            {"carId":5, "carAge":3}
        ]
    },
    {"id":4, "name":"Mary",
        [
            {"carId":3, "carAge":3},
            {"carId":4, "carAge":3}
        ]
    }
]

Edit:

I'm stuck after

list.GroupBy(x => new { x.Id, x.Name })

because I don't need any aggregate functions but only selection.

I apologize for not posting more code, this is a simplified version, the real thing has more filtering and convoluted domain specific terminology.

Everything is done in memory - without DB to worry about.

Tadija Bagarić
  • 2,495
  • 2
  • 31
  • 48
  • 6
    Please show what you have tried. We can help from there. There are many sources to see how to group by and project – Gilad Green Jul 20 '17 at 06:06
  • 2
    Providing a [mcve] would make things simpler, too. It looks like this is a simple `GroupBy` operation where you specific separate key and element selectors, but it would be easier to say for sure with code. – Jon Skeet Jul 20 '17 at 06:08
  • https://stackoverflow.com/questions/2280183/how-to-group-by-custom-types-with-linq should help you. Seems like grouping by the composite key - from 2 values is what you need – Vladimir Jul 20 '17 at 06:12
  • I understand and agree, but the actual code gets complex and I think would distract from the problem, so unfortunately this is the best I can do right now. I made this oversimplified example just so I can explain my question better. – Tadija Bagarić Jul 20 '17 at 06:15

1 Answers1

4

for each section of the group _ by _ expression create an anonymous object with the fields you want.

With any of the following ways you will construct a nested collection for each of your keys - when using a GroupBy it is not just about aggregations but about operations on specific groups of data. One case of it is aggregation methods.

var result = from item in data
             group new { item.carId, item.carAge }  by new {item.id, item.name} into g
             select g;

Another way would be

var result = from item in data
             group  by new {item.id, item.name} into g
             select new {
                 g.Key,
                 Data = g.Select(i => new {i.carId, i.carAge})
             };

Using method syntax as you tried you can use the following overload:

var result = data.Group(k => new {k.id, k.name},
                        e => new {e.carId, e.carAge});

Or if not the just add a Select for projection:

var result = data.Group(k => new {k.id, k.name})
                 .Select(g => new {
                     g.Key,
                     Data = g.Select(i => new {i.carId, i.carAge})
                 });
Gilad Green
  • 36,708
  • 7
  • 61
  • 95