【转】使用 Entity Framework + ListView + DataPager 实现数据分页
l Web程序运行时,页面效果概览
未加载数据时的效果
执行了数据库查询,没有符合条件的结果时的效果
执行了数据库查询,返回10条查询结果时的效果(PageSize设置为5,所以进行了分页)
点击列标题进行排序
DataPager分页控件
l 如何实现自定义组合条件的复杂查询?
实现步骤如下:
1. QueryCondition 类
首先定义一个 QueryCondition 类,包含了查询条件的组合,以及排序规则。
该class中的各个字段都为可空类型,为空即表示不依据该字段查询,从而不需要将参数设置为0或者-1或者“”以表示同样的目的。
其中,PatternQueryKeywordsScope用于定义Keywords查询条件将要覆盖的范围,是标记为 [Flag] 属性的枚举类型,可以将多个枚举值通过 | 运算符累加起来,表示AND或者OR的关系。
PatternQueryOrderBy 则是定义了排序的字段,该字段为nullable,如果为null,则表示由BIZ层业务逻辑代码决定默认的排序字段(通常为ID、DateTime等)。
IsAsc属性(bool类型)定义了排序顺序(升序、降序)。
1. BIZ业务层方法
业务层代码提供了一个 QueryPattern 静态方法,返回类型为:
/// <summary> /// 根据查询条件,搜索符合条件的Pattern数据列表。 /// </summary> /// <param name="con">查询条件对象</param> /// <param name="startRowIndex">开始的记录数(PageSize * PageIndex)</param> /// <param name="maxRowsCount">最大记录数目(PageSize)</param> /// <returns></returns> public static List<Pattern> QueryPattern(PatternQueryCondition con, int startRowIndex, int maxRowsCount){…} |
该方法中,首先判断 PatternQueryCondition 对象是否为空,为空的话,则新建该对象,并设置默认的排序规则。
然后,根据不同的查询参数,调用各自的查询业务逻辑代码。
if (con.CreateUserID.HasValue) patterns = patterns.Where(p => p.CreateUser.UserID == con.CreateUserID.Value); if (string.IsNullOrEmpty(con.CreateUserName) == false) patterns = patterns.Where(p => p.CreateUser.DisplayName.Contains(con.CreateUserName)); if (con.From.HasValue) patterns = patterns.Where(p => p.CreateTime >= con.From.Value); if (con.To.HasValue) patterns = patterns.Where(p => p.CreateTime <= con.To.Value); |
搜索完成后,再处理排序。
也可以先统一调用OrderBy方法,排序完成后根据IsAsc的值,如果IsAsc==false,再调用Reverse方法即进行反序操作。
switch (con.OrderBy.Value) { // other cases… case PatternQueryOrderBy.CreateDate: default: patterns = con.IsAsc == true ? patterns.OrderBy(p => p.CreateTime) : patterns.OrderByDescending(p => p.CreateTime); break; } |
最后,进行分页操作,获得所需要的记录列表。
return patterns.Skip(startRowIndex).Take(maxRowsCount).ToList(); |
2. Web项目中,前端页面代码(.aspx)
显示查询结果的数据列表使用 DataTable 布局,Header(列标题,可点击排序)和 Footer(显示记录数和分页控件)各占一个TR。
中间的数据部分使用了ASP.NET 3.5新的ListView控件,其中LayoutTemplate为空(都在控件外面定义了),仅定义了ItemTemplate和EmptyDataTemplate。
分页使用了ASP.NET 3.5新的DataPager控件,定义如下。
<asp:DataPager ID="dataPagerResults" runat="server" PageSize="5" PagedControlID="listViewResult"> <Fields> <asp:NextPreviousPagerField ButtonType="Link" ShowFirstPageButton="True" ShowNextPageButton="False" FirstPageText="◄◄" LastPageText="►►" NextPageText="►" PreviousPageText="◄" /> <asp:NumericPagerField CurrentPageLabelCssClass="currentPage" /> <asp:NextPreviousPagerField ButtonType="Link" ShowLastPageButton="True" ShowPreviousPageButton="False" FirstPageText="◄◄" LastPageText="►►" NextPageText="►" PreviousPageText="◄" /> </Fields> </asp:DataPager> |
具体分页操作的执行,使用了 ObjectDataSource 控件,其中仅需要指定2个查询方法和查询参数名称。
<asp:ObjectDataSource ID="ObjectDataSourcePatterns" runat="server" SelectMethod="QueryPatterns" TypeName="PatternsAndPractices.WebApp.PnP.Patterns" MaximumRowsParameterName="maxRowsCount" EnablePaging="True" SelectCountMethod="GetQueryCount"> </asp:ObjectDataSource> |
3. Web项目中,页面后台代码(.aspx.cs)
相关页面的后台代码中,首先需要响应 Query Button 的Click事件,根据用户的输入和选择,构造对应的 PatternQueryCondition 对象,然后调用执行数据库查询的方法。
在页面代码中,需要定义如下2个方法,一个用于执行具体的查询操作,一个用于获得该查询条件下,符合条件的记录总数(从而计算出分页总数)。
public List<Pattern> QueryPatterns(int startRowIndex, int maxRowsCount) { return PatternManager.QueryPattern(CurrentPatternQueryCondition, startRowIndex, maxRowsCount); } public int GetQueryCount() { return PatternManager.GetQueryCount(CurrentPatternQueryCondition); } |