EFCore 多字段排序分页法
模型:
public class IPageCommand { public string Keyword { get; set; } public int PageIndex { get; set; } public int PageSize { get; set; } public OrderModelField[] OrderModelField { get; set; } } public struct OrderModelField { public string SortField { get; set; } public bool IsDesc { get; set; } }
方法:
/// <summary> /// 根据条件获取多个实体 /// </summary> /// <param name="where"></param> /// <returns></returns> public List<TResult> GetPageList<TEntity, TResult>(Expression<Func<TEntity, TResult>> select, Expression<Func<TEntity, bool>> where, int pageIndex, int pageSize, out long total, params OrderModelField[] orderByExpression) where TEntity : class { //条件过滤 var query = _context.Set<TEntity>().Where(where); //创建表达式变量参数 var parameter = Expression.Parameter(typeof(TEntity), "o"); if (orderByExpression != null && orderByExpression.Length > 0) { for (int i = 0; i < orderByExpression.Length; i++) { //根据属性名获取属性 var property = typeof(TEntity).GetProperty(orderByExpression[i].SortField); //创建一个访问属性的表达式 var propertyAccess = Expression.MakeMemberAccess(parameter, property); var orderByExp = Expression.Lambda(propertyAccess, parameter); string OrderName = ""; if (i > 0) OrderName = orderByExpression[i].IsDesc ? "ThenByDescending" : "ThenBy"; else OrderName = orderByExpression[i].IsDesc ? "OrderByDescending" : "OrderBy"; MethodCallExpression resultExp = Expression.Call(typeof(Queryable), OrderName, new Type[] { typeof(TEntity), property.PropertyType }, query.Expression, Expression.Quote(orderByExp)); query = query.Provider.CreateQuery<TEntity>(resultExp); } } total = query.Count(); return query.Skip((pageIndex - 1) * pageSize).Take(pageSize).Select(select).ToList(); }
参数:
{ "Keyword": "string", "PageIndex": 2, "PageSize": 5, "OrderModelField": [ { "SortField": "CreateTime", "IsDesc": true}, { "SortField": "String", "IsDesc": true} ] }
调用:
public List<ExampleResult> GetList(PagedCommand Cmd, long total) { return GetPageList<ExampleEntity, ExampleResult>(x => new ExampleResult { Id = x.Id, Boolean = x.Boolean, CreateTime = x.CreateTime, Decimal = x.Decimal, Enum = x.Enum, Float = x.Float, Int = x.Int, String = x.String }, x => x.Boolean, Cmd.PageIndex, Cmd.PageSize, out total, Cmd.OrderModelField); }