转载:http://www.cnblogs.com/ejiyuan/archive/2009/12/22/1629806.html
在LINQ中,IQueryable <T>接口和IEnumerable <T>接口都分别提供了Skip方法和Take方法,用来做分页非常合适.因此我就想用他们做一个分页控件,因为IQueryable <T> 是继承自 IEnumerable <T> 的。因此使用接口仅需要针对后者就可以了。使用的时候只需提供数据源、绑定的GridView的、每页大小即可。现在问题就出了在数据源上,要求用户提供 一个数据源类型,即IQueryable <T>接口和IEnumerable <T>接口? T是可确定类型(已知类型)的话还可以,若T是匿名类型,如
var list = from it in de.Customers where it.City == "abc" select new { it.City, it.Country };
list的类型只有在运行时才能得到,怎么办呢!其实很简单我,我们可以使用 “参数推导泛型类型”的方法来实现:
看下面的代码(因为重点不在这里所以 代码写的比较粗糙):
代码
public void BindBoundControl<TSource>(IEnumerable<TSource> DataSource, GridView BoundControl, int PageSize)
{
//获取总记录数(这里可以使用参数传入总页数 就不必每次都执行下面方法)
int totalRecordCount = DataSource.Count();
//计算总页数
int totalPageCount = 0;
if (PageSize == 0)
{
PageSize = totalRecordCount;
}
if (totalRecordCount % PageSize == 0)
{
totalPageCount = totalRecordCount / PageSize;
}
else
{
totalPageCount = totalRecordCount / PageSize + 1;
}
//从参数中获取当前页码
int CurrentPageIndex = 1;
//如果从参数中获取页码不正确 设置页码为第一页
if (!int.TryParse(HttpContext.Current.Request.QueryString["Page"], out CurrentPageIndex) || CurrentPageIndex <= 0 || CurrentPageIndex > totalPageCount)
{
CurrentPageIndex = 1;
}
//绑定数据源
BoundControl.DataSource = DataSource.Skip((CurrentPageIndex – 1) * PageSize).Take(PageSize);
BoundControl.DataBind();
}
{
//获取总记录数(这里可以使用参数传入总页数 就不必每次都执行下面方法)
int totalRecordCount = DataSource.Count();
//计算总页数
int totalPageCount = 0;
if (PageSize == 0)
{
PageSize = totalRecordCount;
}
if (totalRecordCount % PageSize == 0)
{
totalPageCount = totalRecordCount / PageSize;
}
else
{
totalPageCount = totalRecordCount / PageSize + 1;
}
//从参数中获取当前页码
int CurrentPageIndex = 1;
//如果从参数中获取页码不正确 设置页码为第一页
if (!int.TryParse(HttpContext.Current.Request.QueryString["Page"], out CurrentPageIndex) || CurrentPageIndex <= 0 || CurrentPageIndex > totalPageCount)
{
CurrentPageIndex = 1;
}
//绑定数据源
BoundControl.DataSource = DataSource.Skip((CurrentPageIndex – 1) * PageSize).Take(PageSize);
BoundControl.DataBind();
}
调用
代码
protected void Page_Load(object sender, EventArgs e)
{
NorthwindEntities de = new NorthwindEntities();
BindingUtils bind = new BindingUtils();
//先排序与一下再绑定
bind.BindBoundControl<Customers>(de.Customers.OrderBy(v=>v.CustomerID), this.GridView1, 10);
}
{
NorthwindEntities de = new NorthwindEntities();
BindingUtils bind = new BindingUtils();
//先排序与一下再绑定
bind.BindBoundControl<Customers>(de.Customers.OrderBy(v=>v.CustomerID), this.GridView1, 10);
}
下面我们只是需要重载一下我们的分页方法实现“参数推导泛型类型”就可以了 代码如下:
代码
public void BindBoundControl<TSource>(IEnumerable<TSource> DataSource, TSource type, GridView BoundControl, int PageSize)
{
this.BindBoundControl(DataSource, BoundControl, PageSize);
}
{
this.BindBoundControl(DataSource, BoundControl, PageSize);
}
调用
代码
protected void Page_Load(object sender, EventArgs e)
{
NorthwindEntities de = new NorthwindEntities();
var list = from it in de.Customers where it.City == "abc" select new { it.City, it.Country };
BindingUtils bind = new BindingUtils();
bind.BindBoundControl(list.OrderBy(c=>c.City), list.FirstOrDefault(), this.GridView1, 10);
}
{
NorthwindEntities de = new NorthwindEntities();
var list = from it in de.Customers where it.City == "abc" select new { it.City, it.Country };
BindingUtils bind = new BindingUtils();
bind.BindBoundControl(list.OrderBy(c=>c.City), list.FirstOrDefault(), this.GridView1, 10);
}
这个方法很简单的 只是通过 list.FirstOrDefault() 做参数 来推导 方法中 BindBoundControl<TSource> 的TSource 就可以了,当然因为每次分页时都会执行 list.FirstOrDefault() 会损失一点点的效率。