- 读取大列表中的所有项目
在 SharePoint 2010 中,当您对大型列表执行 SPQuery 时,您会收到异常“禁止尝试的操作,因为它超出了管理员强制执行的列表视图阈值”。为了避免这种异常并批量读取列表项,我们可以使用 Content Iterator。
ContentIterator 有很多可用的方法,这里我们讨论一下http://msdn.microsoft.com/en-us/library/ee560760%28v=office.14%29.aspx
要使用 ContentIterator,请包含 14/ISAPI/ 中可用的 Microsoft.Office.Server.dll 并包含命名空间 Microsoft.Office.Server.Utilities。
优势:
批量获取列表项,减少负载。
如果索引列条件返回的值多于列表视图阈值,则按批处理。在这种情况下,普通 SPQuery 会失败。
我们可以随时停止批处理。
坏处:
您不能在 SPQuery 条件中包含非索引列。
//Run as console application
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.Office.Server.Utilities;
namespace ContentIteratorListItemCollBatch
{
class Sample
{
static int NumberOfBatch = 0, NumberOfItemsRead = 0, NumberOfException = 0;
static void Main(string[] args)
{
using (SPSite site = new SPSite("your site url"))
{
using (SPWeb web = site.OpenWeb())
{
SPList list = web.GetList("Lists/LargeList/AllItems.aspx"); //your list url
ContentIterator ci = new ContentIterator("Reading All Items");
SPQuery qry = new SPQuery();
qry.QueryThrottleMode = SPQueryThrottleOption.Strict; //Ensuring that all users come under List View Threshold. (Including farm admins / box administrators).
qry.RowLimit = 2000; //Number of Items read in a batch. But it should be less than List View Threshold.
qry.Query = qry.Query + ContentIterator.ItemEnumerationOrderByID; //Not Required, Include for faster output.
//Don't use ContentIterator.ItemEnumerationOrderByNVPField, it gets into infinite loop.
ci.ProcessListItems(list, qry, ProcessItemColl, ProcessErrorColl);
Console.WriteLine("\nBatch count: " + NumberOfBatch + "\n\nTotal number of items read: " + NumberOfItemsRead);
Console.ReadLine();
}
}
}
static public bool ProcessErrorColl(SPListItemCollection itemColl, Exception e)
{
// process the error
NumberOfException++;
return true;
}
static public void ProcessItemColl(SPListItemCollection itemColl)
{
//Work on the ListItem Collection object with your own condition
//foreach (SPListItem item in itemColl)
//{
//}
Console.WriteLine("Number of Items Read: " + itemColl.Count);
NumberOfBatch++;
NumberOfItemsRead += itemColl.Count;
}
}
}
我的大列表包含 25,000 项。您可以从输出中看到,它每批 2000 个项目读取 25,000 个项目。
输出
Number of Items Read: 2000
Number of Items Read: 2000
Number of Items Read: 2000
Number of Items Read: 2000
Number of Items Read: 2000
Number of Items Read: 2000
Number of Items Read: 2000
Number of Items Read: 2000
Number of Items Read: 2000
Number of Items Read: 2000
Number of Items Read: 2000
Number of Items Read: 2000
Number of Items Read: 1000
Batch count: 13
Total number of items read: 25000
- 有条件地读取大列表中的项目
确保满足以下条件。
在 where 条件下只允许索引列。
您应该包括 ContentIterator.ItemEnumerationOrderByNVPField。
在下面的代码中,标题是一个索引列。创建自定义列表后,标题将作为索引列。
//作为控制台应用程序运行
使用系统;
使用 System.Collections.Generic;
使用 System.Linq;
使用 System.Text;
使用 Microsoft.SharePoint;
使用 Microsoft.Office.Server.Utilities;
namespace ContentIteratorListItemCollBatch
{
class Sample
{
static int NumberOfBatch = 0, NumberOfItemsRead = 0, NumberOfException = 0;
static void Main(string[] args)
{
using (SPSite site = new SPSite("your site url"))
{
using (SPWeb web = site.OpenWeb())
{
SPList list = web.GetList("Lists/LargeList/AllItems.aspx"); //your list url
ContentIterator ci = new ContentIterator("Reading All Items");
SPQuery qry = new SPQuery();
qry.QueryThrottleMode = SPQueryThrottleOption.Strict; //Ensuring that all users come under List View Threshold. (Including farm admins / box administrators).
qry.RowLimit = 2000; //Number of Items read in a batch. But it should be less than List View Threshold.
qry.Query = @"<Where><Contains><FieldRef Name='Title' /><Value Type='Text'>9</Value></Contains></Where>";
qry.Query = qry.Query + ContentIterator.ItemEnumerationOrderByNVPField;
//Have to include this line.
ci.ProcessListItems(list, qry, ProcessItemColl, ProcessErrorColl);
Console.WriteLine("\nBatch count: " + NumberOfBatch + "\n\nTotal number of items read: " + NumberOfItemsRead);
Console.ReadLine();
}
}
}
static public bool ProcessErrorColl(SPListItemCollection itemColl, Exception e)
{
// process the error
NumberOfException++;
return true;
}
static public void ProcessItemColl(SPListItemCollection itemColl)
{
//Work on the ListItem Collection object with your own condition
//foreach (SPListItem item in itemColl)
//{
//}
Console.WriteLine("Number of Items Read: " + itemColl.Count);
NumberOfBatch++;
NumberOfItemsRead += itemColl.Count;
}
}
}
在 SPQuery 中,如果索引字段获取的次数超过列表视图阈值限制,它将失败。 ContentIterator 通过批处理来处理它。
Output
Number of Items Read: 2000
Number of Items Read: 2000
Number of Items Read: 2000
Number of Items Read: 2000
Number of Items Read: 233
Batch count: 5
Total number of items read: 8233