SharePoint用SPQuery进行查询一直是不错的选择,但是当文件夹,列表,文档库的项目文件数量级比较大的时候,分页是个比较头疼的问题。
本人通过实际测试应用,是可行的
主要思路:
记录SPListItemCollectionPosition的信息,在下次查询时重构SPListItemCollectionPosition,仅仅查询当前页得数据
参考文章:运用SPQuery的RowLimit对SPListItemColliction进行分页 http://bigboy.blog.51cto.com/1212340/272958
改进:在WebPart情况下用Session存储SPListItemCollectionPosition可能出现异常问题,改成存储SPListItemCollectionPosition.PagingInfo
缺点:仅能 前一页后一页
采取的开发模式是WebPart在CreateChildControls是Load用户控件
说明
1.采用了 FriendlyQuery 和 AspNetPager
2.核心方法 GetPagerMode1Items
用户控件代码
用户控件后台代码:
using System;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;
using Microsoft.SharePoint;
using System.Text;
using System.Data;
using System.Collections.Specialized;
namespace Sinopec.NAF.WebParts
{
public partial class BaseMoreControl : System.Web.UI.UserControl
{
#region properties
/// <summary>
/// 相对于SPSite的相对地址
/// </summary>
public string DisWebUrl
{
get
{
if (ViewState["DisWebUrl"] == null)
{
return null;
}
return ViewState["DisWebUrl"].ToString();
}
set
{
ViewState["DisWebUrl"] = value;
}
}
public string DisplayedFolderUrl
{
get
{
if (ViewState["DisplayedFolderUrl"] == null)
{
return null;
}
return ViewState["DisplayedFolderUrl"].ToString();
}
set
{
ViewState["DisplayedFolderUrl"] = value;
}
}
private string _displayFolderUrl;
/// <summary>
/// 页大小
/// 默认为10
/// </summary>
public int PagerPageSize
{
get
{
if (ViewState["PagerPageSize"] == null)
{
return 10;
}
return (int)ViewState["PagerPageSize"];
}
set
{
ViewState["PagerPageSize"] = value;
}
}
private int _pagerPageSize = 10;
/// <summary>
/// 当查询的数据不足时,是否自行填充
/// </summary>
public bool FillData
{
get
{
if (ViewState["AutoFillData"] == null)
{
ViewState["AutoFillData"] = false;
}
return (bool)ViewState["AutoFillData"];
}
set
{
ViewState["AutoFillData"] = value;
}
}
/// <summary>
/// 分页模式
/// 1 前后页码分页模式
/// 2 AspPager分页模式
/// </summary>
public int PagerMode
{
get
{
if (ViewState["PagerMode"] == null)
{
return 2;
}
return (int)ViewState["PagerMode"];
}
set
{
ViewState["PagerMode"] = value;
}
}
/// <summary>
/// FriendlyQuery的查询字符串
/// </summary>
public string SQLQueryStr
{
get
{
if (ViewState["SQLQueryStr"] == null)
{
ViewState["SQLQueryStr"] = string.Empty;
}
return ViewState["SQLQueryStr"].ToString();
}
set
{
ViewState["SQLQueryStr"] = value;
}
}
/// <summary>
/// SPQuery 的查询字符串
/// </summary>
public string QueryString
{
get
{
if (ViewState["QueryString"] == null)
{
return null;
}
return ViewState["QueryString"].ToString();
}
set
{
ViewState["QueryString"] = value;
}
}
/// <summary>
///0 Scope='Default' : 只顯示指定文件夾下的項目及子文件夾
///1 Scope='FilesOnly' : 只顯示指定文件夾下的項目
///2 Scope='Recursive' : 顯示所有項目,不顯示文件夾
///3 Scope='RecursiveAll' : 顯示所有項目和所有子文件
/// </summary>
public int ScopeType
{
get
{
if (ViewState["ScopeType"] == null)
{
return 2;
}
return (int)ViewState["ScopeType"];
}
set
{
ViewState["ScopeType"] = value;
}
}
private int _scopeType = 2;
/// <summary>
/// 标题展现的长度
/// </summary>
public int DisplayedTitleLength
{
get
{
if (ViewState["DisplayedTitleLength"] == null)
{
return 100;
}
return (int)ViewState["DisplayedTitleLength"];
}
set
{
ViewState["DisplayedTitleLength"] = value;
}
}
private int _DisplayedTitleLength = 100;
/// <summary>
/// 标题链接字段
/// </summary>
public string TitleLinkedField
{
get
{
if (ViewState["TitleLinkedField"] == null)
{
return null;
}
return ViewState["TitleLinkedField"].ToString();
}
set
{
ViewState["TitleLinkedField"] = value;
}
}
#endregion
private int repeat = 1;
private int pageIndex = 1;
protected void Page_Load(object sender, EventArgs e)
{
try
{
if (!this.IsPostBack)
{
DeCodeQueryString();
if (PagerMode == 1)
{
PanelPagerMode1.Visible = true;
PanelPagerMode2.Visible = false;
AspNetPager1.Enabled = false;
GetPagerMode1DataAndBindData();
SetPagerMode1PagerButton();
}
else if (PagerMode == 2)
{
PanelPagerMode2.Visible = true;
PanelPagerMode1.Visible = false;
AspNetPager1.Enabled = true;
pageIndex = 1;
GetPagerMode2DataAndBindData();
}
}
}
catch (Exception ex)
{
LogHelper.WriteException(ex);
}
}
#region 前后页分页模式
protected void LBPre_Click(object sender, EventArgs e)
{
try
{
repeat = -1;
GetPagerMode1DataAndBindData();
SetPagerMode1PagerButton();
}
catch (Exception ex)
{
LogHelper.WriteException(ex);
}
}
protected void LBNext_Click(object sender, EventArgs e)
{
try
{
repeat = 1;
GetPagerMode1DataAndBindData();
SetPagerMode1PagerButton();
}
catch (Exception ex)
{
LogHelper.WriteException(ex);
}
}
#endregion
#region AspPager分页模式
protected void AspNetPager1_PageChanged(object src, EventArgs e)
{
try
{
pageIndex = AspNetPager1.CurrentPageIndex;
GetPagerMode2DataAndBindData();
}
catch (Exception ex)
{
LogHelper.WriteException(ex);
}
}
#endregion
#region 前后页分页模式
private void GetPagerMode1DataAndBindData()
{
bool needDispose = false;
SPWeb web = null;
try
{
if (!string.IsNullOrEmpty(DisWebUrl) && DisWebUrl.Trim() != string.Empty)
{
if (DisWebUrl.Trim() == "/")
{
web = SPContext.Current.Site.RootWeb;
}
else
{
web = SPContext.Current.Site.OpenWeb(DisWebUrl);
needDispose = true;
}
}
else
{
web = SPContext.Current.Web;
}
SPFolder folder = web.GetFolder(DisplayedFolderUrl);
if (folder != null && folder.Exists)
{
SPList docLib = web.Lists[folder.ParentListId];
SPListItemCollection itemCol = GetPagerMode1Items(docLib, folder);
if (itemCol != null)
{
DataTable dt = itemCol.GetFullDataTable();
dt.Columns.Add("DisTitle");
dt.Columns.Add("TitleLinkedField");
ModifyDataTable(dt);
RepeaterItems.DataSource = dt;
}
else
{
RepeaterItems.DataSource = null;
}
RepeaterItems.DataBind();
}
}
finally
{
if (needDispose && web != null)
{
web.Dispose();
}
}
}
private SPListItemCollection GetPagerMode1Items(SPList list, SPFolder folder)
{
//确保有查询字符串
if (string.IsNullOrEmpty(SQLQueryStr) || SQLQueryStr.Trim() == string.Empty)
{
SQLQueryStr = string.Format("Select * from {0} Order By Modified Desc", list.Title);
}
//FriendlyQuery 转换成 SPQuery
Sinopec.NAF.FriendlyQuery.FriendlyQuery fq = new Sinopec.NAF.FriendlyQuery.FriendlyQuery(list.ParentWeb, SQLQueryStr);
SPQuery query = fq.GetQuery();
string qString = query.Query;
query.Folder = folder;
//查询文件类型
string st = GetScopeType(ScopeType);
query.ViewAttributes = string.Format("Scope='{0}'", st);
//下面开始做判断,主要运用viewstate来存储相关值;
//查看viewstate是否为空,如果为空,则说明是首次查询,并把queryString的值赋给viewstate;
if (QueryString == null)
{
QueryString = qString;
}
//下面判断不为空的情况,即页面已经做过查询了
else
{
//此处判断queryString是否已改变,即查询条件是否改变
//下面的情况是查询条件改变:
if (QueryString != qString)
{
ViewState["pageinfo"] = null; //这个ViewState是用来存储item.ListItemCollictionPosition;
QueryString = qString;
}
else
{
if (ViewState["pageinfo"] != null && repeat == 1)//repeat是用来区分是上一页还是下一页,1为下一页
{
string strpage = ViewState["pageinfo"].ToString();
if (ViewState["tpageindex"] == null)//用来储存上一页,当前页,下一页的item.ListItemCollictionPosition,通过这个只来判断是那一页;
{
ViewState["tpageindex"] = strpage;
}
else
{
strpage = ViewState["tpageindex"] + ";" + strpage;
ViewState["tpageindex"] = strpage;
}
}
}
}
query.RowLimit = (uint)PagerPageSize;//每页的文档数
if (repeat == 1)
{
if (ViewState["pageinfo"] != null)
query.ListItemCollectionPosition = new SPListItemCollectionPosition(ViewState["pageinfo"].ToString());
}
if (repeat == -1)
{
//处理ViewState["tpageindex"];
if (ViewState["tpageindex"].ToString().Contains(";"))
{
string[] strpage = ViewState["tpageindex"].ToString().Split(';');
ViewState["pageinfo"] = (new Microsoft.SharePoint.SPListItemCollectionPosition(strpage[strpage.Length - 2])).PagingInfo;
query.ListItemCollectionPosition = new SPListItemCollectionPosition(ViewState["pageinfo"].ToString());
ViewState["tpageindex"] = null;
for (int j = 0; j < strpage.Length - 1; j++)
{
if (j == 0)
ViewState["tpageindex"] = strpage[j];
else
ViewState["tpageindex"] = ViewState["tpageindex"] + ";" + strpage[j];
}
}
else
ViewState["tpageindex"] = null;
}
SPListItemCollection items = list.GetItems(query);
//你可以处理你的items了
//最后还要处理item.ListItemCollictionPosition;
query.ListItemCollectionPosition = items.ListItemCollectionPosition;
//Session[ "pageinfo"] = items.ListItemCollectionPosition;
ViewState["pageinfo"] = items.ListItemCollectionPosition == null ? null : items.ListItemCollectionPosition.PagingInfo;
return items;
}
private void SetPagerMode1PagerButton()
{
if (ViewState["pageinfo"] == null)
{
LBNext.Enabled = false;
}
else
{
LBNext.Enabled = true;
}
if (ViewState["tpageindex"] == null)
{
LBPre.Enabled = false;
}
else
{
LBPre.Enabled = true;
}
}
#endregion
#region AspPager分页模式
private DataTable GetPagedItems(DataTable allItems, int pageIndex, int pageSize)
{
if (allItems == null)
{
return null;
}
DataTable retDt = allItems.Clone();
int bePo = (pageIndex - 1) * pageSize;
int endPo = pageIndex * pageSize - 1;
int rowCount = allItems.Rows.Count;
if (bePo > rowCount)
{
return null;
}
endPo = endPo > rowCount - 1 ? rowCount - 1 : endPo;
for (int i = bePo; i <= endPo; i++)
{
retDt.ImportRow(allItems.Rows[i]);
}
retDt.AcceptChanges();
return retDt;
}
private SPListItemCollection GetAllItems(SPList list, SPFolder folder)
{
//确保FriendlyQuery查询字符串
if (string.IsNullOrEmpty(SQLQueryStr) || SQLQueryStr.Trim() == string.Empty)
{
SQLQueryStr = string.Format("Select * from {0} Order By Modified Desc", list.Title);
}
//使用FriendlyQuery获得SPQuery
Sinopec.NAF.FriendlyQuery.FriendlyQuery fq = new Sinopec.NAF.FriendlyQuery.FriendlyQuery(list.ParentWeb, SQLQueryStr);
SPQuery query = fq.GetQuery();
string qString = query.Query;
query.Folder = folder;
//获得查询类型
string st = GetScopeType(ScopeType);
query.ViewAttributes = string.Format("Scope='{0}'", st);
if (QueryString == null)
{
QueryString = qString;
}
else
{
if (QueryString != qString)
{
QueryString = qString;
}
}
SPListItemCollection itemCol = list.GetItems(query);
return itemCol;
}
private void GetPagerMode2DataAndBindData()
{
bool needDispose = false;
SPWeb web = null;
try
{
if (!string.IsNullOrEmpty(DisWebUrl) && DisWebUrl.Trim() != string.Empty)
{
if (DisWebUrl.Trim() == "/")
{
web = SPContext.Current.Site.RootWeb;
}
else
{
web = SPContext.Current.Site.OpenWeb(DisWebUrl);
needDispose = true;
}
}
else
{
web = SPContext.Current.Web;
}
SPFolder folder = web.GetFolder(DisplayedFolderUrl);
if (folder != null && folder.Exists)
{
SPList docLib = web.Lists[folder.ParentListId];
SPListItemCollection itemCol = GetAllItems(docLib, folder);
DataTable allDt = itemCol.GetFullDataTable();
DataTable dt = GetPagedItems(allDt, pageIndex, PagerPageSize);
dt.Columns.Add("DisTitle");
dt.Columns.Add("TitleLinkedField");
ModifyDataTable(dt);
if (itemCol != null)
{
RepeaterItems.DataSource = dt;
RepeaterItems.DataBind();
AspNetPager1.RecordCount = allDt.Rows.Count;
AspNetPager1.PageSize = PagerPageSize;
}
else
{
RepeaterItems.DataSource = null;
RepeaterItems.DataBind();
AspNetPager1.RecordCount = 0;
AspNetPager1.PageSize = PagerPageSize;
}
}
}
catch (Exception ex)
{
LogHelper.WriteException(ex);
}
finally
{
if (needDispose && web != null)
{
web.Dispose();
}
}
}
#endregion
private void ModifyDataTable(DataTable dt)
{
if (dt != null)
{
if (!dt.Columns.Contains("Title"))
{
dt.Columns.Add("Title");
}
if (FillData)
{
FillTableData(dt);
}
for (int i = 0; i < dt.Rows.Count; i++)
{
if (dt.Rows[i]["Title"] != null && DisplayedTitleLength > 0)
{
dt.Rows[i]["DisTitle"] = Utilities.GetLengthString(dt.Rows[i]["Title"].ToString(), DisplayedTitleLength);
}
//默认为ServerUrl
dt.Rows[i]["TitleLinkedField"] = (!string.IsNullOrEmpty(TitleLinkedField) && TitleLinkedField.Trim() != string.Empty) ? dt.Rows[i][TitleLinkedField] : dt.Rows[i]["ServerUrl"];
}
dt.AcceptChanges();
}
}
private string GetScopeType(int st)
{
switch (st)
{
case 0:
return "Default";
case 1:
return "FilesOnly";
case 2:
return "Recursive";
case 3:
return "RecursiveAll";
default:
return "RecursiveAll";
}
}
private void DeCodeQueryString()
{
try
{
NameValueCollection queryStrs = this.Request.QueryString;
string temp = string.Empty;
string webUrl = HttpUtility.UrlDecode(queryStrs.Get("WebUrl"));
if (!string.IsNullOrEmpty(webUrl) && webUrl.Trim() != "")
{
DisWebUrl = webUrl;
}
string folderUrl = HttpUtility.UrlDecode(queryStrs.Get("FolderUrl"));
if (!string.IsNullOrEmpty(folderUrl))
{
DisplayedFolderUrl = folderUrl;
}
temp = HttpUtility.UrlDecode(queryStrs.Get("PS"));
int pageSize = 10;
if (int.TryParse(temp, out pageSize))
{
PagerPageSize = pageSize;
}
temp = HttpUtility.UrlDecode(queryStrs.Get("FD"));
bool fillData = false;
if (bool.TryParse(temp, out fillData))
{
FillData = fillData;
}
temp = HttpUtility.UrlDecode(queryStrs.Get("PM"));
int pagerMode = 2;
if (int.TryParse(temp, out pagerMode))
{
PagerMode = pagerMode;
}
string sqlQueryStr = HttpUtility.UrlDecode(queryStrs.Get("SQL"));
if (!string.IsNullOrEmpty(sqlQueryStr))
{
SQLQueryStr = sqlQueryStr;
}
temp = HttpUtility.UrlDecode(queryStrs.Get("ST"));
int scopeType = 2;
if (int.TryParse(temp, out scopeType))
{
ScopeType = scopeType;
}
temp = HttpUtility.UrlDecode(queryStrs.Get("DTL"));
int displayedTitleLength = 100;
if (int.TryParse(temp, out displayedTitleLength))
{
DisplayedTitleLength = displayedTitleLength;
}
string titleLinkedField = HttpUtility.UrlDecode(queryStrs.Get("TLF"));
if (!string.IsNullOrEmpty(titleLinkedField))
{
TitleLinkedField = titleLinkedField;
}
}
catch (Exception ex)
{
LogHelper.WriteException(ex);
}
}
private void FillTableData(DataTable dt)
{
int rCount = dt.Rows.Count;
if (dt.Rows.Count < PagerPageSize)
{
for (int i = 1; i <= PagerPageSize - rCount; i++)
{
DataRow tempR = dt.NewRow();
dt.Rows.Add(tempR);
}
dt.AcceptChanges();
}
}
}
}