C# 表达式树分页扩展(三)
标签:app HERE 需要 sas 基本 orderby rtb uil direct
一、前言
前面我们知道了表达树的基本知识,也明白了怎么遍历和修改一个表达式,这里我们就一个实际的场景来进行功能开发。
表达式系列目录
C# 表达式树讲解(一)
C# 表达式树遍历(二)
C# 表达式树分页扩展(三)
二、分页扩展
在实际的开发中,肯定会遇到这样的应用场景,一个数据源需要在页面上进行分页显示,并且页面上需要对该数据源有一个排名。本来分页可以在数据库层面完成,但是因为这里有一个排名功能,所谓的排名,就是需要查询出所有满足条件的数据,然后按照某个算法升序或者降序排列,然后按照进行排名。排名之后,然后根据分页信息,将当前页的数据返回给页面,当然中间还有自定义排序的因素。
怎么取数据源和怎么排序,这里先不做介绍,我们就实现对一个数据源分页的功能。
我们先定义好分页的实体对象
分页请求对象PageRequest.cs,因为在【ORM之Dapper运用】已经说明,所以这里我就只粘贴处代码
public class PageRequest
{
///
/// 每页条数
///
public int PageSize { get; set; }
///
/// 当前页数
///
public int PageIndex { get; set; }
///
/// 排序字段
///
public string SortBy { get; set; }
///
/// 排序方式(desc、asc)
///
public string Direction { get; set; }
///
/// 获取排序sql语句
///
///
public string GetOrderBySql()
{
if (string.IsNullOrWhiteSpace(SortBy))
{
return "";
}
var resultSql = new StringBuilder(" ORDER BY ");
string dir = Direction;
if (string.IsNullOrWhiteSpace(dir))
{
dir = "ASC";
}
if (SortBy.Contains("&"))
{
resultSql.Append("").Append(string.Join(",", SortBy.Split(‘&‘).Select(e => $" {e} {dir}").ToArray()));
}
else
{
resultSql.Append(SortBy).Append("").Append(dir);//默认处理方式
}
return resultSql.ToString();
}
}
View Code
分页的返回对象PageResponse.cs
///
/// 通用分页返回
///
///
public class PageResponse
{
///
/// 总条数
///
public long TotalCount { get; set; }
///
/// 返回
///
public List Items { get; set; }
///
/// 当前页
///
public long PageIndex { get; set; }
///
/// 每页条数
///
public long PageSize { get; set; }
///
/// 总页数
///
public long TotalPages { get; set; }
///
/// 返回筛选集合
///
public Dictionarystring, Liststring>> ResultFilter = new Dictionarystring, Liststring>>();
}
View Code
对数据集分页方法的实现
public class PFTPage
{
///
/// 对数据集分页
///
/// 数据集对象
/// 数据集
/// 分页信息
///
public static PageResponse DataPagination(IQueryable source, PageRequest page) where T : class, new()
{
var sesultData = new PageResponse();
bool isAsc = page.Direction.ToLower() == "asc" ? true : false;
string[] _order = page.SortBy.Split(‘&‘);
MethodCallExpression resultExp = null;
foreach (string item in _order)
{
string _orderPart = item;
_orderPart = Regex.Replace(_orderPart, @"\s+", "");
string[] _orderArry = _orderPart.Split(‘ ‘);
string _orderField = _orderArry[0];
bool sort = isAsc;
if (_orderArry.Length == 2)
{
isAsc = _orderArry[1].ToUpper() == "ASC" ? true : false;
}
var parameter = Expression.Parameter(typeof(T), "t");
var property = typeof(T).GetProperty(_orderField);
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var orderByExp = Expression.Lambda(propertyAccess, parameter);
resultExp = Expression.Call(typeof(Queryable), isAsc ? "OrderBy" : "OrderByDescending", new Type[] { typeof(T), property.PropertyType }, source.Expression, Expression.Quote(orderByExp));
}
var tempData = source.Provider.CreateQuery(resultExp);
sesultData.PageIndex = page.PageIndex;
sesultData.PageSize = page.PageSize;
sesultData.TotalCount = tempData.Count();
sesultData.TotalPages = sesultData.TotalCount / sesultData.PageSize;
if (sesultData.TotalCount % sesultData.PageSize > 0)
{
sesultData.TotalPages += 1;
}
sesultData.Items = tempData.Skip(page.PageSize * (page.PageIndex - 1)).Take(page.PageSize).ToList();
return sesultData;
}
}
为了测试,我们定义一个学生课程成绩的测试类
public class ScoreClass
{
public string CourseName { get; set; }
public string StudentName { get; set; }
public decimal Score { get; set; }
}
调用代码
var datas = new List();
datas.Add(new ScoreClass
{
CourseName = "数学",
StudentName = "学生A",
Score = 60
});
datas.Add(new ScoreClass
{
CourseName = "数学",
StudentName = "学生B",
Score = 65
});
datas.Add(new ScoreClass
{
CourseName = "数学",
StudentName = "学生C",
Score = 70
});
datas.Add(new ScoreClass
{
CourseName = "数学",
StudentName = "学生D",
Score = 75
});
datas.Add(new ScoreClass
{
CourseName = "数学",
StudentName = "学生E",
Score = 80
});
datas.Add(new ScoreClass
{
CourseName = "数学",
StudentName = "学生F",
Score = 81
});
datas.Add(new ScoreClass
{
CourseName = "数学",
StudentName = "学生G",
Score = 82
});
datas.Add(new ScoreClass
{
CourseName = "数学",
StudentName = "学生H",
Score = 83
});
datas.Add(new ScoreClass
{
CourseName = "数学",
StudentName = "学生I",
Score = 84
});
//按照Score降序排序取第一个(5条数据)
var page = new PageRequest()
{
Direction= "desc",
PageIndex=1,
PageSize=5,
SortBy= "Score"
};
var result = PFTPage.DataPagination(datas.AsQueryable(), page);
Console.WriteLine($"分页结果:\n{string.Join("\n", result.Items.Select(e=>$"{e.StudentName} {e.CourseName} {e.Score}"))}");
运行结果
监控一下result
返回的都是我们希望返回的数据。
分页公共方法里面,就是根据PageRequest里面的内容,动态的生成表达式树的查询,然后在对数据集使用我们生成的查询表达式树,就返回我们想到的数据集。
三、总结
实现数据分页的公共方法,在后面的遇到数据分页的时候,就会显得非常的方便。有没有感觉很好玩,那么下一篇我们在利用这些知识对Lambda表达式进行扩展。
C# 表达式树分页扩展(三)
标签:app HERE 需要 sas 基本 orderby rtb uil direct
原文地址:https://www.cnblogs.com/snailblog/p/11521359.html
评论