37 votes

Orderby () ne commande pas les numéros correctement c #

Je suis en train d'écrire une application pour mon entreprise et je suis actuellement en train de travailler sur la fonctionnalité de recherche. Lorsqu'un utilisateur recherche un élément, je veux afficher la version la plus récente (qui est stockée dans une base de données).

Le problème est, la version est stockée comme une chaîne de caractères au lieu de int, et quand je fais un OrderBy(q=>q.La Version) sur les résultats, ils sont retournés comme

1
10
11
2
3
...

Évidemment 2 vient avant 10.

Est-il un moyen pour moi de lancer la version comme un entier ou est-il un simple IComparer là-bas? Je ne pouvais pas trouver quoi que ce soit jusqu'à présent.

J'ai essayé de faire ceci:

var items = (from r in results
             select r).OrderBy(q => Int32.Parse(q.Version));

Cette compile mais ne fonctionne pas.

26voto

David B Points 53123

Int32.Parse n'est pas pris en charge par le traducteur LinqToSql. Convert.ToInt32 est pris en charge.

http://msdn.microsoft.com/en-us/library/sf1aw27b.aspx

http://msdn.microsoft.com/en-us/library/bb882655.aspx

7voto

Yuriy Faktorovich Points 33347

Votre problème est ailleurs, les travaux suivants:

 new[] { "1", "10", "2", "3", "11" }
    .OrderBy(i => int.Parse(i))
    .ToList()
    .ForEach(Console.WriteLine);
 

Si votre problème est LINQ to SQL, CLR essaie de créer du SQL à partir de votre LINQ et ne comprend pas int.Parse . Ce que vous pouvez faire, c'est d'abord récupérer les données à partir de SQL, puis les commander une fois que toutes les données sont chargées:

 var items = (from r in results
             select r)
            .ToList()
            .OrderBy(q => Int32.Parse(q.Version));
 

Devrait le faire.

6voto

Damien_The_Unbeliever Points 102139

Si vous ne pouvez pas modifier la définition de votre table (la version est donc de type numérique) et que votre requête est conforme à la liste (vous n'utilisez pas de skip, ni prenez, ou réduisez le nombre de résultats), vous pouvez le faire au mieux. est appelé "ToList" sur les résultats non triés, qui, lorsque vous appliquez ensuite un lambda OrderBY à celui-ci, auront lieu dans votre code, plutôt que d'essayer de le faire à la fin de SQL Server (et qui devrait maintenant fonctionner).

5voto

Thomas Points 42973

Pourquoi êtes-vous le tri dans un lambda? Pourquoi ne pas simplement de tri dans la requête?

var query = from r in items
            orderby int.Parse( r )
            select r;

Maintenant que nous savons que vous êtes à l'aide de LINQ to SQL, vous pourriez envisager de faire un SQL standard d'appel sur ce point en faisant quelque chose comme:

Select ..., Cast( TextWhichShouldBeIntCol As int ) As IntCol
From ...

Ou même

Select ..., Cast( TextWhichShouldBeIntCol As int ) As IntCol
From ...
Order By Cast( TextWhichShouldBeIntCol As int )

Que va saigner dans votre LINQ comme un int (et si vous utilisez la deuxième itération, être ordonnée). Ça évite d'avoir à passer par le jeu de résultats deux fois dans LINQ (une fois pour l'interrogation, une fois pour la commande).

5voto

Leniel Macaferi Points 38324

Il existe un code génial qui fait un excellent travail en matière de tri naturel. Son nom est AlphanumComparator .

Exemple de code:

 var ordered = Database.Cars.ToList().OrderBy(c => c.ModelString, new AlphanumComparator());
 

Notez que la liste doit être en mémoire.

Si vous obtenez la version C #, procédez comme suit:

 AlphanumComparator : IComparer<string>
 

et

 public int Compare(string x, string y)
 

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