使用不同的关键字.net进行排序和筛选



我在前端有一个带有多列和分页的表。用户应该能够对他想要的列进行排序,如果他移动到下一页,那么该页也应该按给定的列排序。

我使用单一排序键和分页的方法:

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

这仅限于按FirstName排序,但如何使用例如LastNameAddress等进行排序。。。?

OrderByDescending采用一个具有两个类型参数的函数:Expression<Func<TSource, TKey>>,其中TKey表示表达式返回的键的类型。

因此,您可以将一个表达式传递给您的方法,并在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);
}

TKey类型参数由表达式推断。因此,它可以如下使用:

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

如果要应用筛选/搜索,则向该方法添加一个新表达式并使用Where:

public List<Person> GetPersons<TKey>(int page, int numPerPage,
Expression<Func<Person, bool>> filter,
Expression<Func<Person, TKey>> orderByDesc)
{
return _context.Person
.Where(filter)
.OrderByDescending(orderByDesc)
.Skip(page*numPerPage)
.Take(numPerPage);
}
// filter by FirstName, order by LastName
var filtered = GetPersons(page, pageSize, 
p => p.FirstName == "Bob", // filter
p => p.LastName);          // orderBy

试试这个扩展方法:

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);
}

您可以将属性名称作为字符串传递,如FirstNameLastNameAddress等。因此,您可以动态订购Persons

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

请参阅:如何使用表达式树构建动态查询

编辑:

另一种可能的解决方案是使用System.Linq.Dynamic,请参阅:https://stackoverflow.com/a/8660293/5519709

最新更新