Home > Blockchain >  Sort and filter with varying key .net
Sort and filter with varying key .net

Time:03-17

I have a table in the frontend with multiple columns and pagination. The user should be able to sort which columns he wants, and if he moves to the next page, that page should also be sorted by the given column.

My approach with a single sort key and pagination:

public List<Person> GetPersons(int page, int numPerPage)
{
   return _context.Person
                  .OrderByDescending(p => p.FirstName)
                  .Skip(page*numPerPage)
                  .Take(numPerPage)
}

This is limited to only sorting by FirstName, but how can I do this with e.g. LastName, Address etc...?

CodePudding user response:

Try this extension method:

public static IQueryable<T> OrderByField<T>(this IQueryable<T> q, string SortField, bool Ascending)
{
    var param = Expression.Parameter(typeof(T), "p");
    var prop = Expression.Property(param, SortField);
    var exp = Expression.Lambda(prop, param);
    string method = Ascending ? "OrderBy" : "OrderByDescending";
    Type[] types = new Type[] { q.ElementType, exp.Body.Type };
    var mce = Expression.Call(typeof(Queryable), method, types, q.Expression, exp);
    return q.Provider.CreateQuery<T>(mce);
}

And you can pass property name as a string like FirstName, LastName or Address etc.. Thus you can order Persons dynamically.

public List<Person> GetPersons(int page, int numPerPage, string orderFieldName)
{
   return _context.Person
                  .OrderByField(orderFieldName, false)
                  .Skip(page*numPerPage)
                  .Take(numPerPage)
}

See: How to use expression trees to build dynamic queries

EDIT:

Another possible solution is using System.Linq.Dynamic see: https://stackoverflow.com/a/8660293/5519709

CodePudding user response:

OrderByDescending takes a function with 2 type parameters: Expression<Func<TSource, TKey>> where TKey represents the type of the key returned by the expression.

Therefore, you could pass an expression to your method and use in the OrderBy:

public List<Person> GetPersons<TKey>(int page, int numPerPage, 
                                     Expression<Func<Person, TKey>> orderByDesc)
{
    return _context.Person
                   .OrderByDescending(orderByDesc)
                   .Skip(page*numPerPage)
                   .Take(numPerPage);
}

The TKey type parameter is inferred by the expression. So, it can be used as below:

var byName = GetPersons(page, pageSize, p => p.FirstName);
var byDate = GetPersons(page, pageSize, p => p.DateOfBirth);
var byHeight = GetPersons(page, pageSize, p => p.Height);
  • Related