正用CSLA.NET做一个Web的项目, 发现CSLA的模型在开发Web时, 不是很适合中国国情.
他的一系列模版, 都是基于主从表单的考虑, 比如"采购单", 这样有单头, 有明细行的情况, 这在WinForm下很棒.
但Web下, 大部分对象都单独用一个表单进行编辑, 所以感觉有些别扭.
我的理解还不深入, 还不断学习中, 整个框架让我受益很多. 废话完了, 进入正题.
要在CSLA模型中方便的使用Sql2005的分页, 我们要做四步.
第一步: 实现一个PagingCriteria, 用来传递分页参数.
[Serializable()]
public class PagingCriteria
{
#region Filed
public IDictionary ParamDic { get; private set; }
public string SortExpression { get; private set; }
public string DefaultOrder { get; private set; }
public int StartRowIndex { get; private set; }
public int MaximumRows { get; private set; }
#endregion
protected PagingCriteria(){ }
public PagingCriteria(IDictionary paramDic, int startRowIndex, int maximumRows, string sortExpression, string defaultOrder)
: base(typeof(T))
{
ParamDic = paramDic;
SortExpression = sortExpression;
DefaultOrder = defaultOrder;
StartRowIndex = startRowIndex;
MaximumRows = maximumRows;
}
}
第二步: 实现PagingWrapper, 将普通的Sql语句封装成可分页的语句.
public static class PagingWrapper
{
private const string SQLTEMPLATE = @"With TargetTable AS(select ROW_NUMBER() OVER (order by Temp.{1})as RowNumber,Temp.* from ({0}) as Temp) select * from TargetTable WHERE RowNumber between {2} and {3};Select count(*) from ({0}) Temp";
public static string Wrap(string sqlQuery, string SortExpression, int startRowIndex, int maximumRows)
{
if (st***g.IsNullOrEmpty(SortExpression))
throw new Exception("未指定排序列.");
return st***g.Format(SQLTEMPLATE, sqlQuery, SortExpression, startRowIndex +1, startRowIndex + maximumRows);
}
public static string Wrap
{
string order = (st***g.IsNullOrEmpty(cr***ria.SortExpression)) ? cr***ria.DefaultOrder : cr***ria.SortExpression;
return Wrap(sqlQuery, order, cr***ria.StartRowIndex, cr***ria.MaximumRows);
}
}
第三部: 在集合对象中调用.这里是RoleList.
using (SqlCommand cm = cn***eateCommand())
{
cm***mmandType = Co***ndType.Text;
string sql = "SELECT * FROM Roles";
cm***mmandText = Pa***gWrapper.Wrap(sql, criteria);
using (SafeDataReader dr = new SafeDataReader(cm***ecuteReader()))
{
while (dr.Read())
Add(Ro***FillRole(dr));
dr***xtResult();
dr.Read();
TotalRowCount = dr***tInt32(0);
}
}CommandText就是调用用Wrapper返回的. TotalRowCount属性是Cs***Core.IReportTotalRowCount接口的实现.
第四步: 在页面上用数据源控件, 绑定Gridview并实现分页:
private int totalCount = 0;
protected void CslaDs_SelectObject(object sender, Cs***Web.SelectObjectArgs e)
{
BL***ecurity.RoleList list = BL***ecurity.RoleList.PagingRoleList(null, e.***tExpression, e.***rtRowIndex, e.***imumRows);
e.***inessObject = list;
totalCount = li***TotalRowCount;
}
protected void gvlist_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.***.RowType == Da***ontrolRowType.Pager)
{
((Label)e.***.FindControl("lblTotal")).Text = to***Count.ToString();
}
}public static RoleList PagingRoleList(IDictionary paramDic, string SortExpression, int startRowIndex, int maximumRows)
{
return Da***ortal.Fetch
}页面Gridview分页部分:
共
你可能会问, 为什么不在Gridview,PagerTemplate中直接写入总行数, 其实是因为Gridview并未暴露这个属性,Sy***m.Web.UI.DataSourceSelectArguments对象,
在获取数据后, 会将总行数返回给Gridview内部, 但Gridview内部会在私有方法中,构一个局部的PagedDataSourse, 将总行数记录在里面, 外部无法获取, 通过反射也不行.
所以最简单的方式, 就是先记下来, 然后在RowDataBound事件中把它写上去. 如果你要求完美, 可以自己封装一个Gridview加上这个TotalRowCount属性,并暴露出来.
上一篇: 分享一个完整的SAP RFC调用接口封装
下一篇: VS2010 Extension实践