Construction d'une expression OrderBy Lambda basée sur la propriété de l'entité enfant

c# expression-trees lambda linq

Question

J'essaie de générer une clause LINQ OrderBy utilisant des expressions lambda avec une entrée du nom de colonne d'une entité sous forme de chaîne (dans la variable "sortOn" ci-dessous).

Le code ci-dessous fonctionne bien pour une valeur sortOn telle que "Code" générant le lambda

p => p.Code

Mais je voudrais aussi trier sur une entité enfant, où le lambda pourrait être

p => p.Category.Description

Donc, dans ce cas, je voudrais juste définir sortOn = "Category.Description" et avoir la bonne expression lamdba générée.

Est-ce possible? Toute suggestion sur la meilleure façon de procéder serait la bienvenue.

Ce code fonctionne bien pour le cas simple:

var param = Expression.Parameter(typeof (Product), "p");

var sortExpression = Expression.Lambda<Func<Product, object>>(
    Expression.Property(param, sortOn), param);

if (sortAscending ?? true)
{
   products = products.OrderBy(sortExpression);
}
else
{
   products = products.OrderByDescending(sortExpression);
}

Le cas d'utilisation de ce problème est d'afficher une grille de données et de pouvoir les trier, simplement en transmettant le nom de la colonne à trier au serveur. J'aimerais rendre la solution générique, mais je commence à utiliser un type particulier (Produit dans l'exemple) pour le moment.

Réponse acceptée

Cela générera une expression lambda appropriée:

var sortOn = "Category.Description";
var param = Expression.Parameter(typeof(Product), "p");
var parts = sortOn.Split('.');

Expression parent = param;

foreach (var part in parts)
{
    parent = Expression.Property(parent, part);
}

var sortExpression = Expression.Lambda<Func<Product, object>>(parent, param);

Réponse populaire

Vous pouvez utiliser la bibliothèque de requêtes Dynamic LINQ pour le faire facilement. En supposant que vous ayez une implémentation IQueryable<T> de Product , vous pouvez facilement faire:

IQueryable<Product> products = ...;

// Order by dynamically.
products = products.OrderBy("Category.Description");

Le blog contient un lien vers la bibliothèque , et vous devrez construire / inclure le projet dans votre solution, mais cela fonctionne très bien et l'analyse est très robuste. Cela vous évite d'avoir à écrire le code d'analyse vous-même; même pour quelque chose d'aussi simple, si les exigences augmentent, la bibliothèque vous couvre, contrairement à une solution maison.

Il dispose également d'un certain nombre d'autres opérateurs dynamiques ( Select , Where , etc.) afin que vous puissiez effectuer d'autres opérations dynamiques.

Il n'y a pas de magie sous le capot, il analyse simplement les chaînes que vous passez et crée ensuite les expressions lambda basées sur les résultats de l'analyse.



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow