Question

Having to do alot of stuff to get IGrouping Working in MVC4 c#. Below are my queries

        var a = (from r in db.SomeProcedure(Id)
                       select new MyClass1
                       {
                           Id= r.Id,
                           Title = r.Title,
                           Name = r.Name,
                           Number = r.Number,
                           Product = r.Product,
                           OtherId = r,OtherId
                       }).ToList();

//The above returns 13 results as expected

        var b = a.GroupBy(x => x.Title ?? "unknown", c => new MyClass2
        {
            Title2 = c.Title,
            Id2 = c.Id,
            OtherId2 = c.OtherId,
            Number2 = c.Number
        });

//The above returns 2 as expected

        List<MyClass1> mClass1 = a;
        List<IGrouping<string,MyClass2>> mClass2 = b.ToList();

//The 2 above are the same as expected

Finally

        mPrivateClass1.Clear();
        mClass1 .ForEach(o => mPrivateClass1.Add(o));

//The above is the 13 as expected

        mPrivateClass2.Clear();
        mClass2 .ForEach(p => mPrivateClass2.AddRange(p));

//The above is returning 13 not 2 as expected. I could not use Add(p) it gives Generic List<> .Add has some invalid arguments.

mPrivateClass1 is a:
 private List<MyClass1> mPrivateClass1 = new List<MyClass1>();

mPrivateClass2 is a:
 private List<MyClass2> mPrivateClass2 = new List<MyClass2>();
Was it helpful?

Solution

mPrivateClass2.Clear();
mClass2 .ForEach(p => mPrivateClass2.AddRange(p));
//The above is returning 13 not 2 as expected.

Why would you like it to return 2 elements only? Because you're using AddRange, the entire grouping content is added into your List, and because IGrouping<TKey, TElement> implements IEnumerable<TElement> will all elements classified to that group, you're getting 13. That's the expected and desired value for your code.

To get only 2 elements in mPrivateClass2 you'd have to decide, which element from the group should be added. For example, to add only the first item from each group use following:

mClass2.ForEach(p => mPrivateClass2.Add(p.First()));

You can add other methods, like OrderBy, to sort the IGrouping content before taking one item:

mClass2 .ForEach(p => mPrivateClass2.Add(p.OrderBy(x => Id).First()));

OTHER TIPS

This is because even though you have 2 groups in mClass2, you have 13 elements combined in the 2 groups, which you are adding as an IEnumerable<MyClass2> when you call mPrivateClass2.AddRange.

Which two elements from each of the groups of MyClass2 would you expect to be added?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top