I want create a dynamic way to return a sorted list by parameter xy. The list can be sorted descending, ascending, by id, username, mail and a lot of more.
I receive this parameter as string. So for example sort=-username
The minus says that the list descending. And the sort parameter is username.
So I return user.OrderByDescending(o => o.Username).ToList();
At the moment with help of a long if-else construct I detect which sorting is needed.
My hope is that I can replace the sort string parameter with help of a function to the object parameter.
Pseudocode
//input for example: sort=-username
Boolean isAscending = isAscending(sort) //return true or false
var parameter = isSortStringInsideObject(sort) //
if (isAscending) {
user.OrderBy(o => o.parameter).ToList();
} else {
user.OrderByDescending(o => o.parameter).ToList();
}
So parameter can be every parameter in object.
I'm new in .net core. So I hope I doesn't formulated an utopian requirement.
Something like this should do the trick (using reflection):
var isAscending = GetIsAscending(sort);
var pi = typeof(User).GetProperty(parameter);
if (pi != null)
user = isAscending
? user.OrderBy(a => pi.GetValue(a, null))
: user.OrderByDescending(a => pi.GetValue(a, null));
Interesting.. it may be also relevant to use System.Linq.Expression namespace to dynamically create a func passed to Order or OrderByDescending, especially if many possible sort parameters are expected.
Eg after we have a string parameter
var parameter = isSortStringInsideObject(sort)
it is possible to construct a function like this (T is the type for the user):
Dictionary<string, PropertyInfo> properties = typeof(T).GetProperties().ToDictionary(pi => pi.Name);
ParameterExpression parameterExpression = Expression.Parameter(typeof(T));
Expression expression = Expression.MakeMemberAccess(parameterExpression, properties[parameter]);
Func<T, string> orderFunc = Expression.Lambda<Func<T, string>>(expression, parameterExpression).Compile();
Looks a little bit heavy :) but it may be effective.
I'd try to keep it typed and use a map with strings to funcs so you can lookup the value coming in and map it.
var list = new List<Item> { new Item() { Name = "aob", Age = 11 }, new Item() {Name = "bob", Age = 10},};
var input = "-name";
var map = new Dictionary<string, Func<Item, object>>()
{
{"name", x => x.Name},
{"age", x => x.Age}
};
if (input.StartsWith('-'))
{
var orderby = map[input.Substring(1)];
var orderedEnumerable = list.OrderByDescending(orderby);
}
else
{
var orderby = map[input];
var orderedEnumerable = list.OrderBy(orderby);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.