迭代一个sharepoint列表

时间:2009-06-08 16:13:11

标签: c# sharepoint

在代码中如何访问sharepoint中的列表,例如“MyList”, 然后遍历此列表项并获取该列表上特定列的值,例如“URL”列?

10 个答案:

答案 0 :(得分:3)

要从列表中检索所有项目并遍历每个项目,最佳解决方案如下(假设此代码作为功能的一部分运行):

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    using(SPSite site = properties.Feature.Parent as SPSite)
    {
        SPList list = site.RootWeb.Lists["ListName"];
        SPListItemCollection items = list.Items;

        foreach (SPListItem listItem in items)
        {
            Response.Write(SPEncode.HtmlEncode(listItem["Url"].ToString()) +"<BR>");
        }
    }
}

但是如果列表非常大,那么最好对列表项进行分页:

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    using(SPSite site = properties.Feature.Parent as SPSite)
    {
        SPList list = site.RootWeb.Lists["ListName"];

        if(items.ItemCount > 100)
        {        
            SPQuery query = new SPQuery();
            query.RowLimit = 100;
            int index = 1;

            do
            {
                SPListItemCollection items = list.GetItems(query);

                foreach (SPListItem listItem in items)
                {
                    Response.Write(SPEncode.HtmlEncode(listItem["Url"].ToString()) +"<BR>");
                }

                query.ListItemCollectionPosition = items.ListItemCollectionPosition;
                index++;

            } while (query.ListItemCollectionPosition != null);
        }
        else
        {
            SPListItemCollection items = list.Items;

            foreach (SPListItem listItem in items)
            {
                Response.Write(SPEncode.HtmlEncode(listItem["Url"].ToString()) +"<BR>");
            }
        }
    }
}

这是基于微软的Best Practices for SharePoint

答案 1 :(得分:2)

来自this blog post

正确的方法是将Items属性返回值存储在SPListItemCollection变量中。这样,数据库只被查询一次,然后我们将遍历存储在集合对象中的结果集。以下是更改的示例代码:

SPListItemCollection items = SPContext.Current.List.Items;
for(int i=0;i<100 && i<items.Count;i++) {
  SPListItem listItem = items[i];
  htmlWriter.Write(listItem["Title"]);
}

答案 2 :(得分:1)

您也可以直接迭代这些项目,如果您使用的是URL字段,则可能需要使用SPFieldUrlValue类,因此您不必处理SharePoint存储URL的方式:

foreach(SPListItem item in spList.Items){
  SPFieldUrlValue data = item["Url"] as SPFieldUrlValue;
  // now you have data.Description, data.Url
}

有许多这样的SPField*辅助类,它们非常有用,特别是当你有多个值时。


编辑:

出于某种原因,有些人认为这种方式较慢,基于Greg帖子的博客文章中的证据(甚至被投了票)。但是,这与我的答案无关:foreach循环创建一个Iterator,因此它不应该多次访问数据库99(在帖子上他们使用for循环来访问前100项)。

答案 3 :(得分:0)

如果您使用某项功能,则会在特定范围内激活该功能(例如,站点,Web,WebApplication或Farm)。

如果要从该功能访问列表,请使用SPFeatureReceiver类将事件接收器绑定到您的功能。然后,在该类中,有触发功能激活事件的覆盖。该覆盖接收SPFeatureReceiverProperties类型的参数。

从该参数

,您可以使用进入网站:

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
  using(SPSite site = properties.Feature.Parent as SPSite) //this depends on scope of feature
  {
    SPList myList = site.RootWeb.Lists["MyList"];
  }
}

如何列出的迭代,请参阅其他答案

答案 4 :(得分:0)

以下是迭代的最佳选择

    SPList list = web.Lists[listname];

    SPQuery query = new SPQuery();
    query.Query = "<OrderBy><FieldRef Name='ID' /></OrderBy>";
    //Scope="Recursive" retrieves items from all folders and subfolders in a list
    query.ViewFields = "<FieldRef Name='" + Lists.MRPLibrary.RebateClaimed + "' /><FieldRef Name='ID'/>";
    query.ViewAttributes = "Scope=\"RecursiveAll\"";
    query.RowLimit = 100;

    do
    {
        SPListItemCollection items = list.GetItems(query);

        foreach (SPListItem listItem in items)
        {

        }

        query.ListItemCollectionPosition = items.ListItemCollectionPosition;

    } while (query.ListItemCollectionPosition != null);

}

答案 5 :(得分:0)

以下用于删除所有批量列表项目的代码,这里可以跳过最新的150个要删除的项目。 通过SPListItemCollection进行迭代,并很快将在2分钟内删除3000个项目,例如3000个项目。

SPList list = web.Lists["DemoDelete"];

SPListItemCollection collListItems = list.GetItems();
var watch = System.Diagnostics.Stopwatch.StartNew();
Console.WriteLine("Start Time: " + watch);
//delete all items uncomment this code
//foreach (SPListItem item in collListItems)
//{
//    SPListItem delItem = list.GetItemById(item.ID);
//    Console.WriteLine("Item Deleted" + delItem.ID);
//    delItem.Delete();
//    list.Update();
//}
//skip lastest 150 items
for (int i = collListItems.Count - 150; i >= 0; i--)
{
SPListItem listItem = list.GetItemById(collListItems[i].ID);  //collListItems[i];
Console.WriteLine("Item Deleted" + listItem.ID);
listItem.Delete();
list.Update();
}

watch.Stop();
var elapsedMs = watch.ElapsedMilliseconds;
Console.WriteLine("End Time: " + elapsedMs);

答案 6 :(得分:-1)

正如其他人所说,你不应该直接迭代Items集合(特别是在大型集合中)。这是一个永恒的:

//如果你需要整个系列。否则在列表中使用SPQuery

DataTable dt = list.Items.GetDataTable();

foreach (DataRow row in dt.Rows)
{
 ...

然后你可以做很多事情。如果您需要检查以获得一些项目,例如:

   if (row["ContentType"].ToString().Equals("Your contenttype id"))
   {
   SPListItem item = list.GetItemById((int)row["ID"]);

或使用SpQuery在查询中获取列,例如:

SPQuery oQuery = new SPQuery();
oQuery.ViewFields = "<FieldRef Name='UrlColumn'/>";

list.Items.GetItems(oQuery).GetDataTable();

...foreach code...
row["UrlColumn"] 

答案 7 :(得分:-1)

如果您在x86环境中,我最近发现了一种非常简单的只读方式来获取MSSQL / OLEDB的数据......

SELECT * FROM OPENROWSET (
    'Microsoft.ACE.OLEDB.12.0',
    'WSS;IMEX=1;RetrieveIds=Yes;DATABASE=http://sharepoint.lsi.local/ops/;LIST={3DCAF100-44A1-4331-8328-748AA98E36AB};',
    'SELECT * FROM list'
)

http://www.connectionstrings.com/sharepoint

答案 8 :(得分:-1)

顺便说一句 使用OPENROWSET时......

IMEX = 2用于读/写。 IMEX = 1是ReadOnly。

List = [Name]适合我而不需要使用list = {GUID}。

答案 9 :(得分:-1)

我知道很久以前就问过这个问题,但我希望我现在可以帮助别人了。)

这就是我能够做到这一点的方式,

// Here comes the query from client.c
n = read(newsockfd, indata, sizeof(int)*length);
if (n < 0) error("ERROR reading from socket");

printf("received %d, expected %lu\n", n, sizeof(int)*length);
square(indata);

// write returns the data to the client
n = write(newsockfd, indata, sizeof(int)*length);
printf("sent %d out of %lu\n", n, sizeof(int)*length);