Zdravo mojstri!
Ciljam na tistih nekaj .NET programerjev, ker (spet :) ) rabim malenkost pomoči.
Zgodba je ta, da imam objekt tipa DataTable, ki ga je treba posortirat glede na stolpce. Glavni trik je pa v tem, da pri pogoju ni vedno isto število stolpcev (lahko je en, lahko jih je pa n).
Vprašanje je torej: ali ima kdo izkušnje, kako dinamično sestavit LINQ sortiranje?
Med brskanjem po netu sem naletel na tole rešitev, konkretno moja implementacija pa izgleda takole:
.
' split all ORDER BY fields by comas
Dim querySegments As String() = sbOrder.ToString.Split(",")
' get the first order by field
Dim firstSegment As String() = querySegments(0).Split(" ")
Dim fieldName As String = firstSegment(0)
' ordered collection for keeping sort results
Dim orderedResults = dtResult.AsEnumerable.OrderBy(Function(f) f.GetItem(fieldName))
' sort by first field (ASC by default, DESC only if provided)
If firstSegment.Length > 1 AndAlso firstSegment(1) = "DESC" Then
orderedResults = dtResult.AsEnumerable.OrderByDescending(Function(f) f.GetItem(fieldName))
End If
' sort by additional fields - segments (if provided - ASC by default, DESC only if provided)
If querySegments.Length > 1 Then
For Each segment As String In querySegments.Skip(1)
Dim subSegment As String() = segment.Trim().Split(" ")
fieldName = subSegment(0)
If subSegment.Length > 1 AndAlso subSegment(1) = "DESC" Then
orderedResults = orderedResults.ThenByDescending(Function(f) f.GetItem(fieldName))
Else
orderedResults = orderedResults.ThenBy(Function(f) f.GetItem(fieldName))
End If
Next
End If
dtResult = orderedResults.CopyToDataTable()
.
Ja, gre za VB - ampak mislim, da noben C# ekspert ne bi smel imet problemov s tem.
Še malenkost razlage:
sbOrder je tak, kot je pri SQL sintaksa za ORDER BY - torej, v stilu "NAZIV ASC, CENA DESC". Ta string se potem razbije na tabelo posameznih polj (querySegments), ki za dan primer izgleda: "NAZIV ASC", "CENA DESC". Potem se pa vsak segment razbije še na subSegment polje, kjer je prvi element ime stolpca (npr. "NAZIV"), drugi element je pa smer ("ASC" oz. "DESC"). Če drugega elementa ni, se predpostavi "ASC".
Problem pri tej implementaciji je, da je rezultat sortiran samo po zadnjem pogoju - čeprav ne bi smel biti, ker naj bi ThenBy oz. ThenByDescending upoštevala predhodne pogoje.
Našel sem tudi DynamicQuery knjižnico, ki vsaj glede na dokumentacijo rešuje ta problem. Ampak preden se spravim kopat v tisto smer, bi najprej rad preveril, če pri trenutni implementaciji delam kakšne neumnosti.
Vsak (s temo povezan) komentar izredno dobrodošel.
And as always: tole ni tema za komentarje "V javi/phpju/rubyju/brainfucku je pa to čist simple narest. M$ sucks.".