Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How To Project a Line Number Into Linq Query Results

How can I project the row number onto the linq query result set.

Instead of say:

field1, field2, field3

field1, field2, field3

I would like:

1, field1, field2, field3

2, field1, field2, field3

Here is my attempt at this:

public List<ScoreWithRank> GetHighScoresWithRank(string gameId, int count)
{
    Guid guid = new Guid(gameId);
    using (PPGEntities entities = new PPGEntities())
    {
        int i = 1;
        var query = from s in entities.Scores
                    where s.Game.Id == guid
                    orderby s.PlayerScore descending
                    select new ScoreWithRank()
                    {
                        Rank=i++,
                        PlayerName = s.PlayerName,
                        PlayerScore = s.PlayerScore
                    };
        return query.ToList<ScoreWithRank>();
    }
}

Unfortunately, the "Rank=i++" line throws the following compile-time exception:

"An expression tree may not contain an assignment operator"

like image 403
Jeff Weber Avatar asked Dec 13 '08 10:12

Jeff Weber


2 Answers

Well, the easiest way would be to do it at the client side rather than the database side, and use the overload of Select which provides an index as well:

public List<ScoreWithRank> GetHighScoresWithRank(string gameId, int count)
{
    Guid guid = new Guid(gameId);
    using (PPGEntities entities = new PPGEntities())
    {
        var query = from s in entities.Scores
                    where s.Game.Id == guid
                    orderby s.PlayerScore descending
                    select new
                    {
                        PlayerName = s.PlayerName,
                        PlayerScore = s.PlayerScore
                    };

        return query.AsEnumerable() // Client-side from here on
                    .Select((player, index) => new ScoreWithRank()
                            {
                                PlayerName = player.PlayerName,
                                PlayerScore = player.PlayerScore,
                                Rank = index + 1;
                            })
                    .ToList();

    }
}
like image 84
Jon Skeet Avatar answered Nov 19 '22 22:11

Jon Skeet


Ok, that did the trick. Thanks.

Here is my final code...

Server:

public List<Score> GetHighScores(string gameId, int count)
{
    Guid guid = new Guid(gameId);
    using (PPGEntities entities = new PPGEntities())
    {
        var query = from s in entities.Scores
                    where s.Game.Id == guid
                    orderby s.PlayerScore descending
                    select s;
        return query.ToList<Score>();
    }                                                                      
}

Client:

void hsc_LoadHighScoreCompleted(object sender, GetHighScoreCompletedEventArgs e)
{
    ObservableCollection<Score> list = e.Result;

    _listBox.ItemsSource = list.Select((player, index) => new ScoreWithRank()
                            {
                                PlayerName = player.PlayerName,
                                PlayerScore = player.PlayerScore,
                                Rank = index+=1
                            }).ToList();
}
like image 1
Jeff Weber Avatar answered Nov 19 '22 22:11

Jeff Weber