简体   繁体   中英

LINQ GroupBy by several values with IComparable exception

I have list with possible values

|Team| |Year| Wins| "Team1" 2014 7 "Team2" 2015 9 "Team1" 2014 8

I wanna get result as

|Team| |Year| Wins| "Team1" 2014 15 "Team2" 2015 9

I try to do that but I get At least one one object must implement Icomparable

 gameResults =
                    gameResults.GroupBy(t => new{t.ContendersName, t.Year})
                    .OrderBy(g => g.Key)
                    .Select(g => new PivotTeamResult()
                       {
                           ContendersName = g.Key.ContendersName,
                           Year = g.Key.Year,
                           Wins = g.Sum(x => x.Wins)                          

                       }).ToList();

I implement IComparable as

public int CompareTo(object obj) {

        PivotTeamResult teamResult = (PivotTeamResult)obj;

        if (this.ContendersName == teamResult.ContendersName)
        {
              return this.Year.CompareTo(teamResult.Year);
        }

        return teamResult.ContendersName.CompareTo(this.ContendersName);
    }

How I can get right result?

I'm not sure but i think your problem lies in OrderBy and not the GroupBy statement. As i see it, you are trying to OrderBy a group key which is not comparable and can't be sorted.

Maybe this will work:

  gameResults =
                gameResults.GroupBy(t => new{t.ContendersName, t.Year})
                .OrderBy(g => g.Key.ContendersName)
                .Select(g => new PivotTeamResult()
                   {
                       ContendersName = g.Key.ContendersName,
                       Year = g.Key.Year,
                       Wins = g.Sum(x => x.Wins)                          

                   }).ToList();

Here you have implemented a comparer for the PivotTeamResult but in the OrderBy clause you are comparing the anonymous type {t.ContendersName, t.Year} so you may perform the order directly like :

gameResults =
                gameResults.GroupBy(t => new{t.ContendersName, t.Year})
                .OrderBy(g => g.Key.ContendersName)
                .ThenBy(g => g.Key.Year)
                .Select(g => new PivotTeamResult()
                   {
                       ContendersName = g.Key.ContendersName,
                       Year = g.Key.Year,
                       Wins = g.Sum(x => x.Wins)                          

                   }).ToList();

Your CompareTo method isn't safe enough because of (PivotTeamResult)obj ; I think that's what you need:

gameResults = gameResults.GroupBy(t => new {t.ContendersName, t.Year}).Select(
                   g => new PivotTeamResult()
                   {
                       ContendersName = g.Key.ContendersName,
                       Year = g.Key.Year,
                       Wins = g.Sum(x => x.Wins)                          

                   }).ToList();

IComparable must be implemented if you want to use OrderBy, Sort or other methods which use object's comparison, in this case it isn't neccessary

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM