Robodude Robodude -3 years ago 88
C# Question

Sorting List of objects with .notation based on inner list

I've got these classes:

[DataContract]
public class RowData
{
[DataMember]
public string ID { get; set; }
[DataMember]
public string AccountName { get; set; }
[DataMember]
public string AuthServerName { get; set; }
[DataMember]
public string SecurityName { get; set; }
[DataMember]
public string LastUser { get; set; }
[DataMember]
public string Status { get; set; }
[DataMember]
public string ClaimRelease { get; set; }
[DataMember]
public List<GameItem> Games { get; set; }
}

[DataContract]
public class GameItem
{
[DataMember]
public string Name { get; set; }
[DataMember]
public string Version { get; set; }
}


I put my best guess non-working query of what it 'should' probably look like if I knew what I was doing.

public List<RowData> GetSortedByColumnList(Entities db, int ColumnID, string direction, int GameCount, List<RowData> rows)
{
...
else if ((ColumnID > 3) && (ColumnID < GameCount + 4))
{
List<Game> gameslist = db.Games
.Where(x => x.GameIsActive == 1)
.ToList(); // Game has the key names

int index = (ColumnID - GameCount) - 1;

// gamename is the name that i'd like to match for sorting purposes.
string gamename = gameslist[index].GameName;

// *** LOOK HERE ****
List<RowData> sortedList = rows
.OrderBy(x => x.Games
.Min(Games => Games.Version)
.Where(Games => Games.Name == gamename))
.ToList();

rows = sortedList;
}


This is a sample of what rows will look like:

rows[0].id = 1
...
rows[0].Games[0].Name="A0"
rows[0].Games[0].Version=3
rows[0].Games[1].Name="B0"
rows[0].Games[1].Version=4

rows[1].id = 2
...
rows[1].Games[0].Name="A0"
rows[1].Games[0].Version=1
rows[0].Games[1].Name="B0"
rows[0].Games[1].Version=2

rows[2].id = 3
...
rows[2].Games[0].Name="A0"
rows[2].Games[0].Version=5


So if string gamename will equal "B0" and I will like the list to be sorted based on the version number so that the sorted order will be row[1], row[2], row[3]. Notice rows[2] doesn't have B0 in it.

How can I modify the query under the
// *** LOOK HERE ****
to get the list sorted as I want?


Compile Error 1 'char' does not contain a definition for 'Name' and no extension method 'Name' accepting a first argument of type 'char' could be found (are you missing a using directive or an assembly reference?)

Answer Source

Assuming that you are looking for a query which will return a list of games with a specific name in order of version, you are probably looking for something similar to the below:

List<GameItem> sortedList = rows
    .SelectMany(r => r.Games) // flattens to an ienumerable of games
    .Where(g => g.Name == gameName) // filters by the game name
    .OrderBy(g => g.Version) // orders by the game's version
    .ToList(); // converts the ienumerable to a list (of games).

If you wanted a List<RowData> instead, and we can assume there is only 1 game with a particular name per row, you could do something like below:

// delegate for generating orderby key    
Func<RowData, string, int> sortKey = (r, gn) =>
{
    var game = r.Games.FirstOrDefault(g => g.Name == gn);
    return game != null ? game.Version : int.MaxValue; // or "zzzzz" if version is a string (something to put it to the end of the list)
};

List<RowData> result = rows
    .OrderBy(r => sortKey(r, gameName))
    .ToList();
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download