C# 迭代共享点列表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/965695/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iterate a sharepoint list
提问by raklos
In code how can I access a list e.g "MyList" in sharepoint, then iterate through this list items and get the value of a particular column on that list e.g the "URL" column?
在代码中,我如何访问一个列表,例如 sharepoint 中的“MyList”,然后遍历此列表项并获取该列表中特定列的值,例如“URL”列?
回答by Greg Hurlman
From this blog post:
来自这篇博文:
The correct way to do it is to store the Items property return value in a SPListItemCollection variable. With this the database is only queried once and we will then iterate over the result set that is stored within the collection object. Here is the changed sample code:
正确的做法是将 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"]);
}
回答by Kobi
You can also iterate the items directly, and if you're using a URL field you probably want to use the SPFieldUrlValue
class, so you don't have to deal with the way SharePoint stores URLs:
您还可以直接迭代项目,如果您使用 URL 字段,您可能希望使用SPFieldUrlValue
该类,这样您就不必处理 SharePoint 存储 URL 的方式:
foreach(SPListItem item in spList.Items){
SPFieldUrlValue data = item["Url"] as SPFieldUrlValue;
// now you have data.Description, data.Url
}
There are many such SPField*
helper classes, and they are very useful, specially when you have multiple values.
有很多这样的SPField*
辅助类,它们非常有用,特别是当您有多个值时。
Edit:
编辑:
For some reason some people believe this way is slower, based on the evidence in the blog post of on Greg's post (even got down voted). This, however, has nothing to do with my answer: a foreach
loop creates an Iterator, so it shouldn't access the database 99 more times (on the post they used a for
loop to access the first 100 items).
出于某种原因,一些人认为这种方式速度较慢,根据 Greg 帖子中的博客文章中的证据(甚至被否决)。然而,这与我的答案无关:foreach
循环创建了一个迭代器,因此它不应再访问数据库 99 次(在他们使用for
循环访问前 100 个项目的帖子中)。
回答by Colin
if you are in a feature, the feature is activated at a specific scope, (e.g. Site, Web, WebApplication or Farm).
如果您在某个功能中,则该功能将在特定范围内激活(例如站点、Web、Web 应用程序或农场)。
When you want to access a list from the feature, use the SPFeatureReceiver class to bind an event receiver to your feature. Then, in that class, there are overrides for when the feature activated event is triggered. that override receives a parameter of type SPFeatureReceiverProperties.
当您想要从功能访问列表时,请使用 SPFeatureReceiver 类将事件接收器绑定到您的功能。然后,在该类中,当触发功能激活事件时有覆盖。覆盖接收 SPFeatureReceiverProperties 类型的参数。
from that parameter, you can use get into a site:
从该参数,您可以使用进入站点:
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"];
}
}
for how the iterate that list, see the orther answers
有关如何迭代该列表,请参阅其他答案
回答by Johan Leino
As others have said, you shouldn′t iterate the Items collection directly (especially in large collections). Here′s an alternaltive:
正如其他人所说,您不应该直接迭代 Items 集合(尤其是在大型集合中)。这是一个替代方案:
// if you need the whole collection. Otherwise use SPQuery on the list
// 如果你需要整个集合。否则使用SPQuery就行了
DataTable dt = list.Items.GetDataTable();
foreach (DataRow row in dt.Rows)
{
...
Then you can do numerous things. If you need to do a check to get only some of the items, ex:
然后你可以做很多事情。如果您需要进行检查以仅获取某些项目,例如:
if (row["ContentType"].ToString().Equals("Your contenttype id"))
{
SPListItem item = list.GetItemById((int)row["ID"]);
or use the SpQuery to get your column in the query, like:
或使用 SpQuery 在查询中获取您的列,例如:
SPQuery oQuery = new SPQuery();
oQuery.ViewFields = "<FieldRef Name='UrlColumn'/>";
list.Items.GetItems(oQuery).GetDataTable();
...foreach code...
row["UrlColumn"]
回答by Josh
If you are in a x86 environment I've recently discovered an awesomely read-only way to get at the data with MSSQL/OLEDB...
如果您在 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'
)
回答by Josh
BTW When using OPENROWSET...
BTW 使用 OPENROWSET 时...
IMEX=2 is for Read/Write. IMEX=1 is ReadOnly.
IMEX=2 用于读/写。IMEX=1 是只读的。
List = [Name] works for me instead of needing to use the list={GUID}.
List = [Name] 对我有用,而不需要使用 list={GUID}。
回答by MagicAndi
To retrieve all items from a list and iterate through each one, the best solution would be as follows (assuming that this code is run as part of a feature):
要从列表中检索所有项目并遍历每个项目,最佳解决方案如下(假设此代码作为功能的一部分运行):
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>");
}
}
}
But if the list is very large, it would be better to paginate through the list items:
但是如果列表非常大,最好对列表项进行分页:
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>");
}
}
}
}
This is based on the Microsoft's Best Practices for SharePoint.
这是基于 Microsoft 的SharePoint 最佳实践。
回答by IE5Master
I know this question was asked a very long time ago but I hope I am able to help someone out now :)
我知道这个问题很久以前就有人问过了,但我希望我现在能够帮助别人:)
This is how I was able to accomplish this,
这就是我能够做到这一点的方式,
protected void Page_Load(object sender, EventArgs e)
{
// Get the current domain
var current = HttpContext.Current.Request.Url.Host;
// We need to tell the SPSite object the URL of where our List is stored.
// Make sure you have the right location placed after the 'current' variable
using (SPSite spSite = new SPSite("http://"+current+"/DirectoryForLists/Lists"))
{
// Returns the Web site that is located at the specified server-relative or site-relative URL.
using (SPWeb spWeb = spSite.OpenWeb())
{
//Get our list we created.
SPList list = spWeb.Lists["Name Of the List"];
// Create a new SPQuery object that will hold our CAML query.
SPQuery q = new SPQuery();
// CAML query.
// This allows you to controll how you receieve your data.
// Make the data ASC or DESC. Find more on MSDN.
q.Query = "<OrderBy><FieldRef Name='DESCR' Ascending='TRUE' /></OrderBy>";
// We put our list data into a SP list Item Collection.
// Notice that the CAML query is the only parameter for the GetItems() function.
SPListItemCollection items = list.GetItems(q);
// Here you can loop through your list.
foreach (SPListItem spItem in items)
{
// Your code here.
MessageBox(spItem);
// Get URL column
MessageBox(spItem["URL"]);
// Another Column
MessageBox(spItem["DateTime"]);
}
}
}
}
回答by user1282548
Below is the best option to iterate
以下是迭代的最佳选择
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);
}
回答by Nagaraju Pattem
Below code used to delete all bulk list items and here can skip latest 150 items to delete. Iterating through SPListItemCollection and very quick time like 3000 items will be delete in 2 mints.
下面的代码用于删除所有批量列表项,此处可以跳过要删除的最新 150 项。遍历 SPListItemCollection 并且非常快,例如 3000 个项目将在 2 分钟内删除。
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);