问题
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?
回答1:
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.
回答2:
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:
SPListItemCollection items = SPContext.Current.List.Items;
for(int i=0;i<100 && i<items.Count;i++) {
SPListItem listItem = items[i];
htmlWriter.Write(listItem["Title"]);
}
回答3:
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:
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.
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).
回答4:
if you are in a feature, the feature is activated at a specific scope, (e.g. Site, Web, WebApplication or Farm).
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.
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
回答5:
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"]);
}
}
}
}
回答6:
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);
}
回答7:
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.
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);
回答8:
As others have said, you shouldn´t iterate the Items collection directly (especially in large collections). Here´s an alternaltive:
// if you need the whole collection. Otherwise use SPQuery on the list
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 oQuery = new SPQuery();
oQuery.ViewFields = "<FieldRef Name='UrlColumn'/>";
list.Items.GetItems(oQuery).GetDataTable();
...foreach code...
row["UrlColumn"]
回答9:
If you are in a x86 environment I've recently discovered an awesomely read-only way to get at the data with 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
回答10:
BTW When using OPENROWSET...
IMEX=2 is for Read/Write. IMEX=1 is ReadOnly.
List = [Name] works for me instead of needing to use the list={GUID}.
来源:https://stackoverflow.com/questions/965695/iterate-a-sharepoint-list