5 Stimmen

Erstellen einer benutzerdefinierten OrderByDescending() für eine IQueryable<T>

Hier sind einige Beispiele für die Werte, die ich gerne von hoch nach niedrig sortieren würde.

8,929 viewers
18,213 viewers
2,223 viewers
41,231 viewers

Und hier ist ein Beispiel für die Abfrage, die ich verwende:

streams = streamRepository.FindAll()
                          .OrderByDescending(s => s.ViewCount)
                          .Take(4);

Dies funktioniert nicht korrekt, da ich mir vorstelle, dass der Parameter als String und nicht als Int angenommen wird, aber das ist nicht überraschend.

Wie empfehlen Sie, dass ich diese "Bestellung" mit sauberen C# / Linq-Code erstellen?

Im Idealfall würde sich unter Verwendung der oben genannten Datenbeispiele eine geordnete Menge ergeben:

41,231 viewers
18,213 viewers
8,929 viewers
2,223 viewers

1voto

Justin Niessner Punkte 235353

Wenn das Format immer das gleiche ist, würde ich es ausprobieren:

streams = streamRepository.FindAll()
    .AsEnumerable()
    .OrderByDescending(s => 
        int.Parse(s.ViewCount.Substring(0, s.ViewCount.IndexOf(' ') - 1))
    .Take(4);

1voto

Arion Punkte 30771

Vielleicht nicht die schönste Lösung. Aber vielleicht so etwas wie dies:

streamRepository.FindAll()
        .OrderByDescending(t => t =>Convert.ToDouble(
                 t.ViewCount.Substring(0,t.ViewCount.IndexOf(' '))))

Die generierte Sql. Erhalten Sie nicht, dass schrecklich und es funktioniert in linqpad:

-- Region Parameters
DECLARE @p0 Int = 0
DECLARE @p1 NChar(1) = ' '
-- EndRegion
SELECT [t0].[SomeText]
FROM [Table1] AS [t0]
ORDER BY CONVERT(Float,SUBSTRING([t0].[SomeText], @p0 + 1, 
    (CASE 
        WHEN (DATALENGTH(@p1) / 2) = 0 THEN 0
        ELSE CHARINDEX(@p1, [t0].[SomeText]) - 1
     END))) DESC

Weil linq übersetzen kann substring y indexof zu Sql-Funktionen. Aber das ist auch sehr spezifisch für das Format. Wie in dem Kommentar zu Ihrer Frage würde ich auch vorschlagen, dass Sie die Spalte in zwei Spalten aufteilen.

0voto

Etwas wie (mehr Pseudo, habe nicht auf alles getestet, sollte aber nahe dran sein)...

streams = streamRepository.FindAll()
                          .Select(s=> new { Original = s, Count = ParseToInt(s.ViewCount)})
                          .OrderByDescending(a => a.Count)
                          .Take(3);

...wo ParseToInt ist ein einfaches Parsen dieser Zeichenkette in nur count (nur Split auf ' ' und nehmen erste Parse in int ich schätze)

Ich hoffe, das hilft ein wenig

EDITAR: dies würde für ein Szenario ohne Db funktionieren

Im Falle der Db gebundene Abfrage - Sie müssten die "Zeichenfolge" in int mit einigen SQL-Funktion, die zugeordnet ist (und kann zu SQL von linq zugeordnet werden) - aber ich bin nicht sicher, sofort, was wäre der beste Weg, das zu tun. Außerdem müssten Sie einen Select machen, damit Sie alle Daten herausbekommen.
In diesem Fall ist es wahrscheinlich am besten, ein int-Feld in der Datenbank zu behalten (anstelle eines Strings).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X