Est-il possible de créer une expression de requête réutilisable avec des appels à OrderBy
et Where
, sans l'appliquer à un spécifique?Requête de méthode LINQ réutilisable
Je voudrais pouvoir faire quelque chose comme ceci:
var data = new List<PlayerDTO>();
var builder = new Builder<PlayerDTO>();
var query = builder.GetQuery();
var results = data.AsQueryable().Provider.CreateQuery(query);
J'ai du mal à obtenir que cela fonctionne sans fournir l'objet IQueryable
à la méthode GetQuery
.
Ceci est le code que j'ai jusqu'à présent:
public Expression GetQuery()
{
var type = typeof(T); // T is PlayerDTO
var col = type.GetProperty(OrderBy.Column);
var orderByMethod = typeof(Queryable).GetMethods().Single(
method => method.Name == "OrderBy"
&& method.IsGenericMethodDefinition
&& method.GetGenericArguments().Length == 2
&& method.GetParameters().Length == 2);
var genericOrdebyMethod = orderByMethod.MakeGenericMethod(typeof(T), col.PropertyType);
var parameter = Expression.Parameter(typeof(T), "p"); // {p}
var property = Expression.Property(parameter, col); // {p.ID}
var lambda = Expression.Lambda<Func<T, int>>(property, parameter); // {p => p.ID}
//This list should not exist here
var tempList = new List<PlayerDTO>() { new PlayerDTO(1, "First"), new PlayerDTO(2, "Second") };
var orderByMethodExpression = Expression.Call(genericOrdebyMethod, tempList.AsQueryable().Expression, lambda); // {tempList.OrderBy(p => p.ID)}
var results = tempList.AsQueryable().Provider.CreateQuery(orderByMethodExpression);
return orderByMethodExpression;
}
La partie pertinente est l'appel à Expression.Call
, où je devais fournir une IQueryable
il donc travailler, mais je voudrais être en mesure de construire l'expression sans spécifier un IQueryable
existant.
Est-ce encore possible?
Edit:
Maintenant que je pense à cela, je ne ont pas besoin réellement faire du tout ... Il est parfaitement logique de simplement envoyer le IQueryable en tant que paramètre à la méthode GetQuery. Je vais garder cette question si.
ne pouvez-vous utiliser seulement 'Expression> = p => p.ColumnName;'? Vous pouvez utiliser cette expression dans votre méthode 'OrderBy'. Cela fonctionnerait si votre PlayerDTO implémente une interface pour connaître la propriété columnName. Sinon, vous pouvez toujours utiliser la réflexion juste pour la propriété. –
Oui, je pourrais, mais mon problème principal est avec les méthodes de type OrderBy/Where/etc que je voudrais inclure dans l'expression, puis réutiliser sur plusieurs IQueryables. –
C'est juste un peu bizarre ce que vous faites, construire dynamiquement une expression, en utilisant Provider pour le transformer en iQueryable, alors que vous savez exactement à l'avance quelle propriété vous utiliserez et quelle méthode. Le Linq extensionmethods sur 'IQueryable 'fait exactement la même chose que vous essayez de faire manuellement maintenant (voir [ce lien] (https://referencesource.microsoft.com/#System.Core/System/Linq/IQueryable.cs , 7a2005ae434e9d9d, références)). –