Mvc 分页

1:当设计到有多张表是通常提取需要的相关展示字段,然后把它封装成一个视图模型:比如

public class UserSearchView
{
public int UserId { get; set; }

public string CompanyName { get; set; }

public string CompanySiteURL { get; set; }

public bool? IsBuildRelation { get; set; }

/// <summary>
/// 行业Id
/// </summary>
public int BusinessId { get; set; }

public string Province { get; set; }

public string City { get; set; }

/// <summary>
/// 行业名称
/// </summary>
public string Business { get; set; }

/// <summary>
/// 微博数量
/// </summary>
public int MicroblogCount { get; set; }

/// <summary>
/// 启用的微博账号数量
/// </summary>
public int EnabledAccountCount { get; set; }
}

2: 然后定义个分页的数据源:

/// <summary>
/// 分页数据源
/// </summary>
/// <typeparam name="T"></typeparam>
public class PagingDataSource<T>
{
public int PageSize { get; set; }

public int PageIndex { get; set; }

public int RecordCount { get; set; }

public IList<T> DataSource { get; set; }

public PagingDataSource(IList<T> dataSource, int pageIndex, int pageSize, int recordCount = 0)
{
DataSource = dataSource;
PageSize = pageSize;
PageIndex = pageIndex;
RecordCount = recordCount;
}

public PagingDataSource(IList<T> dataSource, PagingQuery pagingQuery, int recordCount = 0) :
this(dataSource, pagingQuery.PageIndex, pagingQuery.PageSize, recordCount)
{
}
}

public static class PagingDataSourceExtensions
{
public static PagingDataSource<T> ToPagingDataSource<T>(this IList<T> dataSource, int pageIndex, int pageSize, int recordCount = 0)
{
return new PagingDataSource<T>(dataSource, pageIndex, pageSize, recordCount);
}

public static PagingDataSource<T> ToPagingDataSource<T>(this IList<T> dataSource, PagingQuery pagingQuery, int recordCount = 0)
{
return new PagingDataSource<T>(dataSource, pagingQuery, recordCount);
}

}

3:定义相关的查询条件:

3.1 定义一个公用的:PagingQuery

/// <summary>
/// 分页索引
/// </summary>
public int PageIndex { get; set; }

/// <summary>
/// 每一页的数量 默认为20
/// </summary>
public int PageSize { get; set; }

/// <summary>
/// 是否获取总数
/// </summary>
public bool IsGetRecordCount { get; set; }

public PagingQuery()
{
PageIndex = 1;
PageSize = 20;
IsGetRecordCount = true;
}
}

public static class PagingQueryExtensions
{
public static int GetSkipCount(this PagingQuery query)
{
return (query.PageIndex - 1)*query.PageSize;
}
}

3.2

定义查询条件视图:UserSearchViewQuery:PagingQuery

public int CurrentUserId { get; set; }

/// <summary>
/// 要查询的行业Id
/// </summary>
public int BusinessId { get; set; }
/// <summary>
/// 要查询的区域
/// </summary>
public string Province { get; set; }
/// <summary>
/// 要查询的公司
/// </summary>
public string CompanyName { get; set; }

public int requestUserId { get; set; }

4:相关的方法编写

public PagingDataSource<UserRepostRelation> GetListByRepostRelationQuery(RepostRelationQuery repostRelationQuery)
{
var query = this.Where(r => r.IsBuildRelation == repostRelationQuery.IsBuildRelation);
switch (repostRelationQuery.QueryType)
{
case RepostRelationQuery.QueryConditionType.RequestList:
query = query.Include(r => r.ReceiveUser);
query = query.Where(r => r.RequestUserId == repostRelationQuery.UserId);
break;
case RepostRelationQuery.QueryConditionType.ReceiveList:
query = query.Include(r => r.RequestUser);
query = query.Where(r => r.ReceiveUserId == repostRelationQuery.UserId);
break;
case RepostRelationQuery.QueryConditionType.AnyList:
query = query.Include(r => r.RequestUser).Include(r => r.ReceiveUser);
query = query.Where(
r =>
r.ReceiveUserId == repostRelationQuery.UserId || r.RequestUserId == repostRelationQuery.UserId);
break;
}

int recordCount = query.Count();
IList<UserRepostRelation> dataSource =
query.OrderByDescending(r => r.Id).Skip(repostRelationQuery.GetSkipCount()).Take(
repostRelationQuery.PageSize).ToList();

return dataSource.ToPagingDataSource(repostRelationQuery, recordCount);
}

5 view 展示数据

5.1 首先应用相关的命名空间

@using Saifutong.Weibo.Domain.QueryCondition
@model Saifutong.Weibo.Domain.ViewModel.PagingDataSource<Saifutong.Weibo.Domain.ViewModel.UserSearchView>
@{
ViewBag.Title = "找企业 - 赛富通微聚合";
UserSearchViewQuery query = ViewData["Query"] as UserSearchViewQuery;
}

5.2 定义分页部分方法

public static class PagerExtensions
{
internal const string PAGE_INDEX_NAME = "pageindex";
internal const string PAGE_SIZE_NAME = "pagesize";

public static MvcHtmlString Pager<TModel>(this HtmlHelper<PagingDataSource<TModel>> htmlHelper, PagingDataSource<TModel> pagedEntity)
{
return GeneratePagerHtml<TModel>(htmlHelper, htmlHelper.ViewContext.RequestContext, pagedEntity);
}

public static MvcHtmlString Pager<TModel>(this HtmlHelper htmlHelper, PagingDataSource<TModel> pagedEntity)
{
return GeneratePagerHtml<TModel>(htmlHelper, htmlHelper.ViewContext.RequestContext, pagedEntity);
}

private static MvcHtmlString GeneratePagerHtml<TModel>(HtmlHelper htmlHelper, RequestContext context, PagingDataSource<TModel> pagedEntity)
{
if (pagedEntity == null)
throw new ArgumentNullException("pagedEntity");

StringBuilder html = new StringBuilder();
UrlHelper urlHelper = new UrlHelper(context);

int pageNumber = pagedEntity.PageIndex;
int totalItemCount = pagedEntity.RecordCount;
int totalpage = (int)Math.Ceiling(totalItemCount / (double)pagedEntity.PageSize);
int currentPageIndex = pagedEntity.PageIndex;
bool hasPreviousPage = currentPageIndex > 1;
bool hasNextPage = currentPageIndex < totalpage;

// 呈现分页信息
html.AppendLine(GeneratePagingLink(currentPageIndex > 1, GeneratePagingLinkUrl(context, 1), "第一页"));
html.AppendLine(GeneratePagingLink(hasPreviousPage, GeneratePagingLinkUrl(context, pageNumber - 1), "前一页"));
html.AppendLine(string.Format("<span class=\"page-num\">总计 {0} 记录 当前第 {1} 页共 {2} 页</span>",
totalItemCount, pageNumber, totalpage));
html.AppendLine(GeneratePagingLink(hasNextPage, GeneratePagingLinkUrl(context, pageNumber + 1), "下一页"));
html.AppendLine(GeneratePagingLink(currentPageIndex < (totalpage - 1), GeneratePagingLinkUrl(context, totalpage), "最后一页"));

html.Append("<form method=\"get\">");
var queryString = context.HttpContext.Request.QueryString;
foreach (var name in queryString.AllKeys)
{
if (!string.Equals(name, "page", StringComparison.CurrentCultureIgnoreCase))
html.Append(htmlHelper.Hidden(name, queryString[name]).ToString());
}
html.Append(" 跳至第 ");
html.Append(htmlHelper.TextBox(PAGE_INDEX_NAME, pageNumber, new { @class = "gotoBox", style = "width:30px" }).ToString());
html.Append(" 页 <input type=\"submit\" value=\"Go\" /></form>");
return MvcHtmlString.Create(html.ToString());
}

public static MvcHtmlString NumericPager<TModel>(this HtmlHelper htmlHelper, PagingDataSource<TModel> pagedEntity)
{
return NumericPager<TModel>(htmlHelper, pagedEntity, false);
}

public static MvcHtmlString NumericPager<TModel>(this HtmlHelper htmlHelper, PagingDataSource<TModel> pagedEntity, bool showInOnPage)
{
return GeneratePagerHtml<TModel>(htmlHelper, htmlHelper.ViewContext.RequestContext, pagedEntity, showInOnPage);
}

public static MvcHtmlString NumericPager<TModel>(this HtmlHelper<PagingDataSource<TModel>> htmlHelper, PagingDataSource<TModel> pagedEntity)
{
return NumericPager<TModel>(htmlHelper, pagedEntity, false);
}

public static MvcHtmlString NumericPager<TModel>(this HtmlHelper<PagingDataSource<TModel>> htmlHelper, PagingDataSource<TModel> pagedEntity, bool showInOnPage)
{
return GeneratePagerHtml<TModel>(htmlHelper, htmlHelper.ViewContext.RequestContext, pagedEntity, showInOnPage);
}

private static MvcHtmlString GeneratePagerHtml<TModel>(HtmlHelper html, RequestContext context, PagingDataSource<TModel> pagedEntity, bool showInOnPage)
{
if (pagedEntity == null)
throw new ArgumentNullException("pagedEntity");

var queryString = html.ViewContext.HttpContext.Request.QueryString;
int currentPage = pagedEntity.PageIndex; //当前页
var totalPages = Math.Max((pagedEntity.RecordCount + pagedEntity.PageSize - 1) / pagedEntity.PageSize, 1); //总页数
var dict = new RouteValueDictionary(html.ViewContext.RouteData.Values);

var output = new StringBuilder();

foreach (string key in queryString.Keys)
if (queryString[key] != null && !string.IsNullOrEmpty(key))
dict[key] = queryString[key];

if (totalPages > 1)
{
output.Append("<div class=\"pager\">");

if (currentPage != 1)
{//处理首页连接
dict[PAGE_INDEX_NAME] = 1;
output.Append(html.RouteLink("首页", dict));
}
if (currentPage > 1)
{//处理上一页的连接
dict[PAGE_INDEX_NAME] = currentPage - 1;
output.Append(html.RouteLink("上一页", dict));
}
else
{
output.Append("<span class=\"disabled\">上一页</span>");
}
int currint = 5;
for (int i = 0; i <= 10; i++)
{//一共最多显示10个页码,前面5个,后面5个
if ((currentPage + i - currint) >= 1 && (currentPage + i - currint) <= totalPages)
if (currint == i)
{//当前页处理
output.Append(string.Format("<span class=\"current\">{0}</span>", currentPage));
}
else
{//一般页处理
dict[PAGE_INDEX_NAME] = currentPage + i - currint;
output.Append(html.RouteLink((currentPage + i - currint).ToString(), dict));
}
}
if (currentPage < totalPages)
{//处理下一页的链接
dict[PAGE_INDEX_NAME] = currentPage + 1;
output.Append(html.RouteLink("下一页", dict));
}
else
{
output.Append("<span class=\"disabled\">下一页</span>");
}
if (currentPage != totalPages)
{
dict[PAGE_INDEX_NAME] = totalPages;
output.Append(html.RouteLink("末页", dict));
}
//output.AppendFormat("{0} / {1}", currentPage, totalPages); //统计
output.Append("</div>");
}

return MvcHtmlString.Create(output.ToString());
}

private static string GeneratePagingLink(bool hasLink, string linkUrl, string linkText)
{
if (hasLink)
return string.Format("<a href=\"{0}\">{1}</a>", linkUrl, linkText);
else
return string.Format("<span class=\"nopaging\">{0}</span>", linkText);
}

private static string GeneratePagingLinkUrl(RequestContext context, int page)
{
HttpRequestBase req = context.HttpContext.Request;
string url = req.FilePath;
var queryStrings = new NameValueCollection(req.QueryString);

if (queryStrings.AllKeys.Contains(PAGE_INDEX_NAME)) // 已有分页参数
queryStrings[PAGE_INDEX_NAME] = page.ToString();
else
queryStrings.Add(PAGE_INDEX_NAME, page.ToString());

List<string> qs = new List<string>();
foreach (string s in queryStrings)
{
qs.Add(s + "=" + queryStrings[s]);
}

return string.Concat(new string[] { url, "?", string.Join("&", qs.ToArray()) });
}

}

5.3

调用方法:

@Html.NumericPager(Model)

6 控制器

UserSearchViewQuery userSearchViewQuery = new UserSearchViewQuery();
UpdateModel(userSearchViewQuery);
userSearchViewQuery.CurrentUserId = UserId;
userSearchViewQuery.PageSize = PAGE_SIZE;

ViewBag.Query = userSearchViewQuery;

posted @ 2012-11-28 11:50  历史的驱动  阅读(922)  评论(0编辑  收藏  举报