1

like the title said I have to group by age and gender but I get this error message:

At least one object must implement IComparable

var ageStats = vModel
               .GroupBy(l => new { Age = 10 * (l.Age / 10), l.GenderName })
               .OrderBy(x => x.Key)
               .Select(g => new
                            {
                                Name = g.Key,
                                Count = g.Select(l => l.Age).Count()
                            })
               .ToList();

If I group by age only like that it will work .GroupBy(l => 10 * (l.Age / 10)) but I won't have the gender.

Luiso
  • 4,173
  • 2
  • 37
  • 60
David Létourneau
  • 1,250
  • 2
  • 19
  • 39
  • What's the type of `GenderName`? – Servy Jun 14 '16 at 20:50
  • The type of GenderName is string – David Létourneau Jun 14 '16 at 20:52
  • 1
    have you tried using tuples instead of anonymous objects? – Luiso Jun 14 '16 at 20:58
  • @Luiso's suggestion of using Tuples is a good one. Tuples implement `IComparable`. – wablab Jun 14 '16 at 21:04
  • 1
    @Luiso Tuples are almost always a bad idea, just create a class, especially as it looks like OP is going to use the result as is. – DavidG Jun 14 '16 at 21:08
  • @Luiso IMHO, Tuples are a bad idea when you return them from an API or, in general, a method from a class. All you can see is the type of each element, but you have no idea what each element represents. If you use the Tuple wholly within the LINQ query, then it wouldn't be as bad because you can simply glance up to see what each element represents. – Kenneth K. Jun 14 '16 at 21:10
  • You might could do something like http://stackoverflow.com/a/1071637/884561, where you pass an instance of your new `IEqualityComparer` to the `GroupBy` as a second parameter. – Kenneth K. Jun 14 '16 at 21:14
  • 2
    @KennethK. I agree with you, but if that query is being used inside a method, and you know what you're doing, they can save some time and having to implement an almost useless class – Luiso Jun 14 '16 at 21:15
  • @Luiso Sorry, I meant to direct that comment toward DavidG. – Kenneth K. Jun 14 '16 at 22:38

2 Answers2

2

When you ordering your group results you using Key that in your case is complex anonymouse type contains 2 fields:

var ageStats = vModel
               .GroupBy(l => new { Age = 10 * (l.Age / 10), l.GenderName })
               .OrderBy(x => x.Key) //<-- this line
               .Select(g => new
                            {
                                Name = g.Key,
                                Count = g.Select(l => l.Age).Count()
                            })
               .ToList();

It works with only Age grouping becouse anonymouse type in this case simple int field.

If you want to order your results somehow you should point to field like this:

.OrderBy(x => x.Key.Age)

Or this:

.OrderBy(x => x.Key.GenderName)

If you want to order first by Age then by GenderName use ThenBy extension method like this:

.OrderBy(x => x.Key.Age).ThenBy(x => x.Key.GenderName)
teo van kot
  • 12,350
  • 10
  • 38
  • 70
-1

When you do:

new { Age = 10 * (l.Age / 10), l.GenderName }

you're creating an anonymous type, which I don't believe implements IComparable. When you leave out the braces and the , l.GenderName, the result of the expression is an int, which does implement IComparable.

wablab
  • 1,703
  • 13
  • 15
  • Leaving out the `, l.GenderName` wouldn't perform the group that he wants. – Kenneth K. Jun 14 '16 at 21:05
  • I think this answer explains the compilation error, but @Luiso's comment about Tuples on the original post provides a good answer. – wablab Jun 14 '16 at 21:05
  • @KennethK., I wasn't suggesting that this would perform the grouping he wanted. But point taken: this wasn't an 'answer', so I should've posted it as a comment. – wablab Jun 14 '16 at 21:07
  • @wablab your answer correct, it's more like x y problem. – teo van kot Jun 14 '16 at 21:27