34 votes

Comment projeter un numéro de ligne dans les résultats de requête Linq

Comment puis-je projeter le numéro de ligne sur le jeu de résultats de la requête linq.

Au lieu de dire:

champ1, champ2, champ3

champ1, champ2, champ3

J'aimerais:

1, champ1, champ2, champ3

2, champ1, champ2, champ3

Voici ma tentative:

 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>();
    }
}
 

Malheureusement, la ligne "Rank = i ++" lève l'exception de compilation suivante:

"Une arborescence d'expression ne peut pas contenir d'opérateur d'affectation"

55voto

Jon Skeet Points 692016

Eh bien, le moyen le plus simple serait de le faire côté client plutôt que côté base de données, et d'utiliser la surcharge de Select qui fournit également un index:

 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();

    }
}
 

1voto

Jeff Weber Points 564

Ok, ça a fait l'affaire. Merci.

Voici mon code final ...

Serveur:

 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();
}
 

0voto

shannonlh Points 39

Vous pouvez également apporter un léger ajustement à votre code d'origine pour le faire fonctionner. Attention, si vous liez des données ou accédez à nouveau à l'objet, le rang augmentera à chaque fois. Dans ces cas, la meilleure réponse est meilleure.

 let Rank = i++
 

et

 Rank.ToString()
 

Code complet:

 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
                let Rank = i++
                where s.Game.Id == guid
                orderby s.PlayerScore descending
                select new ScoreWithRank()
                {
                    Rank.ToString(),
                    PlayerName = s.PlayerName,
                    PlayerScore = s.PlayerScore
                };
    return query.ToList<ScoreWithRank>();
}
 

}

0voto

Onur Bıyık Points 350

Cette solution a fonctionné pour moi. http://www.dotnetfunda.com/articles/article1995-rownumber-simulation-in-linq.aspx

 .Select((x, index) => new
{
     SequentialNumber = index + 1
    ,FieldFoo = x.FieldFoo                        
}).ToList();
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X