Getting list item field values from a SP List using Client Object Model
What is the optimal way to get a list items and their properties from a SP list using Client object model?
Here is the code I'm using.
string server = "http://localhost";
ClientContext context = new ClientContext(server);
Web web = context.Web;
var spList = web.Lists.GetByTitle("Contact");
CamlQuery query = new CamlQuery();
var items = spList.GetItems(query);
context.Load(items,
itema => itema.Include(
item => item,
item => item["CustomerId"]));
context.ExecuteQuery();
Console.WriteLine("Items");
foreach (var item in items.ToList())
{
context.Load(item);
}
context.ExecuteQuery();
foreach (var item in items)
{
foreach (var a in item.FieldValues)
{
Console.WriteLine(a.Key + ":" + a.Value.ToString());
}
}
I want to remove the single liner foreach used to load list item in the context and if possible load the item field values in the first Execute Query itself.
I tried using the following
context.Load(items,
itema => itema.Include(
item => item,
i开发者_开发百科tem=> item.FieldValues,
item => item["CustomerId"]));
which doesn't work.
Any one can provide a cleaner solution?
The most efficient way to query SharePoint is to use a CAML Query. By calling (SP)List.GetItems(camlQuery). You will receive always an instance of (SP)ListItemCollection.
So the the most efficient query will look like this
string server = "http://localhost";
var ctx = new ClientContext(server);
var web = ctx.Web;
var list = web.Lists.GetByTitle("Contacts");
var listItemCollection = list.GetItems(CamlQuery.CreateAllItemsQuery());
// always use QueryTrimming to minimize size of
// data that has to be transfered
ctx.Load(listItemCollection,
eachItem => eachItem.Include(
item => item,
item => item["CustomerId"]));
// ExecuteQuery will pull all data from SharePoint
// which has been staged to Load()
ctx.ExecuteQuery();
foreach(ListItem listItem in listItemCollection)
{
Console.WriteLine(listItem["CustomerId"]);
}
Thorsten
I am not 100% sure what properties you would like to get from the fields but you could play around with the following:
SPSite oSite = new SPSite("http://localhost");
SPWeb oWeb = oSite.OpenWeb();
SPList oList = oWeb.Lists["LIST NAME"];
SPFieldCollection oFields = oList.Fields;
foreach (SPField oField in oFields)
{
Console.WriteLine("Property: " + oField.GetProperty("PROPERTY"));
}
OR
The property you are looking for may actually be under the SPField object. Take a look here for the properties and methods available: http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spfield_members(v=office.12).aspx
Hope this helps. If not some more info on what actual properties you want to get out of the lists' fields might help provide a more accurate solution?
Change your code to this.
IQueryable<ListItem> items = spList.GetItems(query);
Then call LoadQuery() instead of Load()
context.LoadQuery(items);
You may add additional expressions to read the property of the ListItem
you wanted like this:
context.LoadQuery(items.Include(item => item["CustomerId"]));
I am actually having problem trying to do item => item.FieldValues
, but item => item.FieldValuesAsText
works. I am not sure why :( But just doing context.LoadQuery(items)
should do what you want.
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = "<View Scope=\"RecursiveAll\"><Query><Where><Eq><FieldRef Name=\"FSObjType\" /><Value Type=\"Integer\">0</Value></Eq></Where></Query><RowLimit>100</RowLimit></View>";
ListItemCollection listItemCollection = srcList.GetItems(camlQuery);
srcContext.Load(listItemCollection);
await srcContext.ExecuteQueryAsync();
Querying for FSObjType=0 returns the items with all fields populated! See: https://blog.velingeorgiev.com/sharepoint-online-csom-all-list-items-content-caml-query
The query gets all list items in batches of 100. May you just could add an AND clause to the query to get specific items.
精彩评论