web-dev-qa-db-fra.com

Ordonnance () ne commandant pas les numéros correctement c #

J'écris une application pour ma société et je travaille actuellement sur la fonctionnalité de recherche. Lorsqu'un utilisateur cherche un élément, je souhaite afficher la version la plus élevée (qui est stockée dans une base de données).

Le problème est que la version est stockée comme une chaîne à la place de l'INT, et lorsque je fais une ordonnance (q => q.version) sur les résultats, ils sont retournés comme

1
10
11
2
3
...

Évidemment 2 vient avant 10.

Y a-t-il un moyen pour moi de jeter la version comme un entier ou y a-t-il un simple iComparer? Je n'ai rien trouvé substantiel jusqu'à présent.

J'ai essayé de faire ça:

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

Cela compile mais ne fonctionne pas.

37
Darcy

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

26
Amy B

Votre problème est ailleurs, les œuvres suivantes:

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

Si votre problème est linq à SQL, ce qui se passe est CLR essaie de créer SQL hors de votre LINQ et ne comprend pas int.Parse. Ce que vous pouvez faire est d'abord obtenir les données de SQL puis commandez-la 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.

7

Si vous ne pouvez pas modifier la définition de votre table (la version est donc un type numérique), et votre requête est réellement comme indiqué (vous n'utilisez pas d'ignorer, ou de prendre ou de réduire autrement le nombre de résultats), le meilleur que vous puissiez faire Est-ce que Call "Tolist" sur les résultats non acheminés, qui, lorsque vous appliquez ensuite une ordonnance en Lambda, il aura lieu dans votre code, plutôt que d'essayer de le faire à l'extrémité SQL Server (et qui devrait maintenant fonctionner).

6

Pourquoi tu tries dans une Lambda? Pourquoi ne faites-vous pas juste trier dans la requête?

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

Maintenant que nous savons que vous utilisez LINQ vers SQL, vous pourriez envisager de faire un appel SQL standard sur celui-ci 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 )

Cela saignera dans votre LINQ en tant que INT (et si vous utilisez la deuxième itération, soyez commandé). Cela évite de devoir passer à deux reprises les Resulats à Linq (une fois pour interrogé, une fois pour la commande).

5
Thomas

Il y a un code de 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 #, faites ceci:

AlphanumComparator : IComparer<string>

et

public int Compare(string x, string y)
5
Leniel Maccaferri
var items = (from r in results
         select r).OrderBy(q => Convert.ToInt32(q.Version));

Définitivement courir ......

1
Sunil Dhanerwal

J'ai fait un test. J'ai le code suivant.

string[] versions = { "1", "2", "10", "12", "22", "30" };
foreach (var ver in versions.OrderBy(v => v))
{
     Console.WriteLine(ver);
}

Comme prévu, le résultat est de 1, 10, 12, 2, 22, 30, puis permet de modifier versions.OrderBy(v => v)) à versions.OrderBy(v => int.Parse(v))). Et ça marche bien: 1, 2, 10, 12, 22, 30

Je pense que votre problème est que vous avez des caractères Nondigit dans votre chaîne comme ".". Quel genre d'exception obtenez-vous?

1
ILya

essaye ça:

var items = results.(Select(v => v).OrderBy(v => v.PadLeft(4));

ça va travailler dans linq2sql

1
Mike Jacobs

On dirait que vous avez une valeur de texte au lieu d'une valeur numérique.

Si vous avez besoin de trier, vous pouvez essayer:

var items = (from r in results
             select r);
return items.OrderBy( v=> Int.Parse(v.Version) );
0
chris
var query = from r in items
            let n = int.Parse(r)
            orderby n
            select n;
0
Alxandr
var items = (from v in results
                    select v).ToList().OrderBy(x => int.Parse(x.Version));
0
Steven Williams