Linq Group By Return Type

madaxe2020

Well-known member
Joined
Sep 7, 2020
Messages
50
Programming Experience
5-10
The code runs but i dont know how to get a specified type

I want to get a IEnumerable<IEnumerable<ConnectionModel>> something with a defined type, but im struggling on casting to this data type

can somebody help?

Thanks

Madaxe

Linq Groupby:
var Someobject = AllConnectionModels.OrderBy(x => x.Nomenclature)
                   .GroupBy(x => x.Nomenclature)
                   .Select(g => new
                   {
                       Connections = g.Select(
                           connection => new ConnectionModel(
                               connection.Nomenclature,
                               connection.Offset,
                           connection.AsDesigned_Layer)
                       )
                   }).ToList();

ConnectionModel:
public class ConnectionModel
    {
        public string Nomenclature { get; set; }
        public double Offset { get; set; }
        public double Cummulativeoffset { get; set; }
        public int AsDesigned_Layer { get; set; }
        public Object NewScrewStartObject { get; set; } = null;
        public Object NewScrewEndObject { get; set; } = null;
        public Object NewArrowObject { get; set; } = null;

        public ConnectionModel() { }

        public ConnectionModel(string Nomenclature, double Offset, int AsDesigned_Layer)
        {
            this.Nomenclature = Nomenclature;
            this.Offset = Offset;
            this.AsDesigned_Layer = AsDesigned_Layer;
        }
 
The problem is that you create an anonymous type, that can't be a method return type. Happens at Select(g => new { ... }

I wonder if your query is just an 'accident' trying to get to some 'result':
  • Is losing the grouping key a choice?
  • Is creating new ConnectionModel objects a choice?
If not you could stop at the GroupBy and you get a IEnumerable<IGrouping<string, ConnectionModel>> with the same result of your current query. Each item is a group, the group has a Key and contains each ConnectionModel item.

If you for example want to make the type simpler you add this to the GroupBy: .Select(g => g.ToArray()).ToArray() to make a ConnectionModel[][] (jagged array) using the existing ConnectionModel objects.

Another example adding to GroupBy: .Select(g => g.Select(c => c)) and you get <IEnumerable<IEnumerable<ConnectionModel>> using the existing ConnectionModel objects.
Or adding .Select(g => g.Select(c => new ConnectionModel(c.Nomenclature, c.Offset, c.AsDesigned_Layer))) for same result type, but here new ConnectionModel object are created.
 
I feel this is clearer and more direct to the point:
C#:
var Someobject = AllConnectionModels
                    .OrderBy(x => x.Nomenclature)
                    .GroupBy(x => x.Nomenclature)
                    .Cast<IEnumerable<ConnectionModel>>();
 
Thanks for all the help i tool it one step further with the following solution

Thanks

Madaxe

Final Solution:
            Dictionary<string, List<ConnectionModel>> Someobject3 = AllConnectionModels
                    .OrderBy(x => x.Nomenclature)
                    .GroupBy(x => x.Nomenclature)
                    .ToDictionary(g => g.Key, g => g
                    .OrderBy(o => o.AsDesigned_Layer)
                    .ThenBy(o => o.Offset).ToList());
 
Back
Top Bottom