J'utilise des datatables dans plusieurs pages sur mon site ASP.NET MVC 3. Ils utilisent la pagination côté serveur et maintenant je veux implémenter le tri basé sur les en-têtes de colonne. Les données sont fournies avec iSortCol_0
, qui est une valeur int de la colonne sur laquelle on clique.Get Dynamic OrderBy dans LINQ
Je n'ai pas aimé cette approche que la requête finirait par quelque chose comme:
if(iSortCol_0 == 0)
{
// query
// OderBy(x => x.CarName)
}
Ensuite, ce sera répété pour chaque colonne (plus une clause else sur chaque à l'ordre par ordre décroissant). J'ai donc changé d'approche et passe maintenant le nom de la colonne au serveur.
Je suis venu avec ce qui suit:
Expression<Func<vw_Car, string>> sortExpression1 = null;
Expression<Func<vw_Car, int>> sortExpression2 = null;
switch(columnToSort)
{
case "InvoiceNo": sortExpression1 = x => x.CarNo; break;
case "ClientNumber": sortExpression1 = x => x.ForeName; break;
case "ClientName": sortExpression1 = x => x.SurName; break;
default: sortExpression2 = x => x.Age.Value; break;
}
// start of query
.OrderByDir(sortDirection, sortExpression1 , sortExpression2)
Maintenant, le OrderByDir
ressemble ci-dessous:
public static IOrderedQueryable<T> OrderByDir<T>(this IQueryable<T> source, string dir, Expression<Func<T, string>> column1, Expression<Func<T, int>> column2)
{
if (column1 != null)
{
return dir == "asc" ? source.OrderBy(column1) : source.OrderByDescending(column1);
}
if (column2 != null)
{
return dir == "asc" ? source.OrderBy(column2) : source.OrderByDescending(column2);
}
return null;
}
Cela fonctionne en ce qu'elle trie les colonnes qui sont de type string
ou int
. J'ai une autre colonne de DateTime
que je veux trier, donc je devrais écrire un autre sortExpression3
puis l'ajouter à mon OrderByDir
.
Cependant, je ne aime pas vraiment la mise en œuvre - j'avais essayé d'écrire une expression générique de tri qui a un objet comme second paramètre au lieu de string
, int
, Datetime
, mais quand a ce code en place, je recevais Impossible de convertir le type 'System.DateTime' en type 'System.Object'. LINQ to Entities ne prend en charge que les types primitifs de modèle de données d'entité de diffusion.
Quelqu'un at-il des idées quant à une meilleure approche possible à cela?
Pourquoi deux sortExpressions? En fonction de votre code, l'expression un ou l'expression deux est définie mais jamais les deux en même temps. Est-ce correct? –
@mattytommo: Non applicable, citation "Je suppose que vous avez seulement besoin de prendre en charge LINQ to Objects". –
@DanielHilgarth - parce que l'une des expressions de tri est pour la colonne Âge (un champ int) - l'autre expression de tri est pour les colonnes de chaîne –