supposons que j'ai deux classes: Ces classes sont plus ou moins données, elles sont mappées via NHibernate pour être honnête :) p> dans une grille ( Datatables.net comme base) Je souhaite avoir un tri indépendant de type. P> Par conséquent, j'ai créé une expression lambda: p> si je passe la personne comme type T et remplacez la "propriété à trier" avec "nom" Ça fonctionne bien (crée une lambda correcte) . Si la propriété de tri est "adresse.street", il ne fonctionnera pas, jette-moi l'erreur suivante: p> Je ne vois qu'une solution jusqu'à présent, mais pas assez clairement ... J'essaierais de scinder la chaîne qui contient le nom de la propriété (Split by.) P> Quelqu'un peut-il donner une meilleure solution? Je dois ajouter la solution Extrait à un objet iquéry Je ne sais pas si mon titre est clair, allez-y et corrigez-le. P> Merci d'avance. P> P> Query.orderby (Sortexpression) Code>. P>
4 Réponses :
Il me semble que vous essayez de réécrire Microsoft DynamicQuery . Pourquoi pas simplement l'utiliser à la place?
Voici un exemple: P>
IQueryable<Foo> myQuery = GetHibernateQuery(); myQuery = myQuery.OrderBy("address.street");
Parce que je reçois seulement un objet iquérisable qui contient déjà un tas de données, alors j'ajoute la pagination et ainsi de suite, puis je charge que les données laissées dans la requête. Ceci est fait par NHibernate. Seulement pour le tri ne peut pas être la solution (j'espère)
C'est mon point. DynamicQuery peut déjà faire cela "Ajouter le tri à un requérant existant". J'ai une solution de démonstration sur mon blog qui fait exactement cela. blogs.teamb.com/craigstzz/2009/04/27/38243 a>
J'ai ajouté un exemple trivial au poste.
Qu'est-ce qui n'est pas clair?
Vous devez le diviser, puis utiliser: p>
uhm et comment feriez-vous cela si peut-être y a-t-il quelque chose comme person.company.address.street code>? Je ne sais tout simplement pas comment "nich" .. ou s'il y a d'autres façons, comme Craig posté ...
Expression.property (expression.property (expression.property (expression.property (param, "personne"), "Société"), "Adresse"), "Street") La boucle simple fonctionnera.
Voici une version plus générique de la réponse de Lukled: Vous pouvez l'utiliser comme ceci: p>
C'est une méthode excellente et réutilisable pour résoudre ce problème. Merci.
Excellente réponse +1. Vous pouvez le faire dans une doublure: renvoyer la propriétéName.split ('.'). Agrégat (expression, (corps, membre) => expression.propertyorfield (corps, membre); >.
Si vous n'aimez pas que vous n'aimez pas la fantaisie, une version plus lisible utilise une version plus lisible utilise foreach code>, comme:
corps d'expression = expression; foreach (membre var inactename.split ('.')) {corps = expression.propertyorfield (corps, membre); } retour corps; code>
Essayez celui-ci
public static IQueryable<T> SortIQueryable<T>(IQueryable<T> data, string fieldName, string sortOrder) { if (string.IsNullOrWhiteSpace(fieldName)) return data; if (string.IsNullOrWhiteSpace(sortOrder)) return data; var param = Expression.Parameter(typeof(T), "i"); MemberExpression property = null; string[] fieldNames = fieldName.Split('.'); foreach (string filed in fieldNames) { if (property == null) { property = Expression.Property(param, filed); } else { property = Expression.Property(property, filed); } } Expression conversion = Expression.Convert(property, typeof(object));//Expression.Property(param, fieldName) var mySortExpression = Expression.Lambda<Func<T, object>>(conversion, param); return (sortOrder == "desc") ? data.OrderByDescending(mySortExpression) : data.OrderBy(mySortExpression); }