27
Techniques to Access List Data Rob Windsor [email protected] @robwindsor

Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor - SPTec…

Embed Size (px)

DESCRIPTION

Full-Day Tutorial Sunday, March 3 9:00 AM - 5:00 PM

Citation preview

Page 1: Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor - SPTec…

Techniques to Access

List Data

Rob Windsor

[email protected]

@robwindsor

Page 2: Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor - SPTec…

Lists

• The data storage mechanism in SharePoint

Virtually all content stored in lists

• Provisioning engine handles list creation and schema management

• SharePoint provides interface to add, edit, delete and view items

• Lists support:

Multiple views (for sorting, filtering, grouping)

Simple validation

Content approval

Item versioning

• Data stored in rows and columns

More like Excel worksheets than database tables

Page 3: Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor - SPTec…

Accessing and Updating List Items

• Field values accessed via SPListItem indexer

• Generally accessed by internal name

• Weakly typed

var web = SPContext.Current.Web;

var list = web.Lists.TryGetList("Products");

if (list == null) return;

foreach (SPListItem item in list.Items)

{

Console.WriteLine("{0} ({1})",

item["Title"],

item["UnitPrice"]);

}

var web = SPContext.Current.Web;

var list = web.Lists.TryGetList("Products");

if (list == null) return;

foreach (SPListItem item in list.Items)

{

var price = Convert.ToDouble(

item["UnitPrice"]);

price *= 1.1;

item["UnitPrice"] = price;

item.Update();

}

Page 4: Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor - SPTec…

Field Names

• Fields have three names

Display name

The name displayed to the end user

Can be changed

Internal name

Set when field is created

Does not change

Non-alphanumeric chars escaped (e.g. Unit_x0020_Price)

Find using Server Explorer

Static name

Used by custom field types

Page 5: Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor - SPTec…

CAML Queries

• Query list items using XML syntax

• SPQuery

Query single list

Returns SPLitsItemCollection

• SPSiteDataQuery

Query multiple lists across site collection

Returns DataSet

• Use QueryThrottleMode to enable/disable throttling

Enabled by default

Page 6: Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor - SPTec…

CAML Queries

var query = new SPQuery();

query.ViewFields =

"<FieldRef Name='Title' />" +

"<FieldRef Name='UnitPrice' />";

query.Query =

"<OrderBy>" +

" <FieldRef Name='Title' />" +

"</OrderBy>" +

"<Where>" +

" <And>" +

" <Gt>" +

" <FieldRef Name='UnitsInStock' />" +

" <Value Type='Integer'>0</Value>" +

" </Gt>" +

" <Eq>" +

" <FieldRef Name='Category' LookupId='True' />" +

" <Value Type='Lookup'>1</Value>" +

" </Eq>" +

" </And>" +

"</Where>";

var items = list.GetItems(query);

Page 7: Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor - SPTec…

SPQuery.ViewAttributes

• Scope Default = Show files and folders of specific folder

FilesOnly = Show files of specific folder

Recursive = Shows files in all folders

RecursiveAll = Show files and folders in all folders

• Moderation HideUnapproved = Don’t show draft items

Contributor = Show draft items for current user only

Moderator = Show draft items

• Syntax Query.ViewAttributes = "Scope='Recursive'"

Page 8: Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor - SPTec…

“All we can do is decide what to do with

the time tools that is are given us”

Image from The Lord of the Rings: The Fellowship of the Ring by New

Line Cinema

Page 9: Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor - SPTec…

Large List Throttling

• Lists can store millions of items

• Retrieval of items is throttled

Max 5,000 items

Max 20,000 for Owners

No max for local admin

• Can override limits in code

QueryThrottleMode

• Can configure time window

where limits are ignored

For reporting, list aggregation, etc

Done during off-peak hours

Page 10: Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor - SPTec…

Paging CAML Queries

• Seriously convoluted for all but the simplest cases

• Paging managed by SPListItemCollectionPosition Only supports Prev / Next paging

Cannot jump to a specific page

• PagingInfo String representing the parameters used to get the next page of

items

Parts Paged=TRUE – the list is paged

PagedPrev=TRUE – retrieve the previous page

p_ID=n – list item id of the first or last value in the set last retrieved

p_<Field Name>=v - value of first or last value of the order by field in the set last retrieved

PageFirstRow – the position of the last item in the last set retrieved

Page 11: Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor - SPTec…

CAML Queries

var list = SPContext.Current.Web.Lists["Announcements"]; var query = new SPQuery(); query.RowLimit = 10; query.Query = "<OrderBy Override=\"TRUE\">" + "<FieldRef Name=\"FileLeafRef\" /></OrderBy>"; do { var items = list.GetItems(query); // work with items query.ListItemCollectionPosition = items.ListItemCollectionPosition; } while (query.ListItemCollectionPosition != null);

Page 12: Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor - SPTec…

List Relationships

Page 13: Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor - SPTec…

Joins in CAML Queries

• SPQuery supports joins SPSiteDataQuery does not

• Joins can only be done on lookup columns

• Key properties J oins: Define joins to other lists

ProjectedFields: Fields being projected from the foreign list

• Only inner and left outer joins are supported

Page 14: Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor - SPTec…

SPQuery with Join Example

var query = new SPQuery { RowLimit = 5 };

query.ProjectedFields =

"<Field Name='CategoryTitle' Type='Lookup' List='productCategory' ShowField='Title' />";

query.ViewFields =

"<FieldRef Name='Title' />" +

"<FieldRef Name='UnitPrice' />" +

"<FieldRef Name='UnitsInStock' />" +

"<FieldRef Name='CategoryTitle' />";

query.Query =

"<Where>" +

" <And>" +

" <Gt>" +

" <FieldRef Name='UnitsInStock' />" +

" <Value Type='Integer'>0</Value>" +

" </Gt>" +

" <Eq>" +

" <FieldRef Name='CategoryTitle' />" +

" <Value Type='Text'>Condiments</Value>" +

" </Eq>" +

" </And>" +

"</Where>";

query.Joins =

"<Join Type='INNER' ListAlias='productCategory'>" +

" <Eq>" +

" <FieldRef Name='Category' RefType='ID' />" +

" <FieldRef List='productCategory' Name='ID' />" +

" </Eq>" +

"</Join>";

return list.GetItems(query);

Page 15: Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor - SPTec…

Querying Multiple Lists with SPSiteDataQuery

• Core properties the same as SPQuery

• Cannot query lists outside site collection

• Key additional properties

Lists

Defines which lists will be included in query

Use ServerTemplate for OOB content types

Use BaseType plus filter for ID in where clause for custom content

types

Webs

Defines the scope of the query

SiteCollection

– Query all matching lists in site collection

Recursive:

– Query all matching lists in current Web and it’s children

Page 16: Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor - SPTec…

SPSiteDataQuery Example

var query = new SPSiteDataQuery { RowLimit = 50 };

query.ViewFields =

"<FieldRef Name='Title' />" +

"<FieldRef Name='DueDate' />" +

"<FieldRef Name='AssignedTo' />";

query.Query =

"<Where>" +

" <And>" +

" <Geq>" +

" <FieldRef Name='DueDate' />" +

" <Value Type='DateTime'><Today /></Value>" +

" </Geq>" +

" <Leq>" +

" <FieldRef Name='DueDate' />" +

" <Value Type='DateTime'><Today OffsetDays='5' /></Value>" +

" </Leq>" +

" </And>" +

"</Where>";

query.Lists =

"<Lists ServerTemplate='107' />"; <!– Task Lists -->

query.Webs =

"<Webs Scope='SiteCollection' />";

return web.GetSiteData(query);

Page 17: Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor - SPTec…

DEMO List access using Server

Object Model

Page 18: Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor - SPTec…

REST APIs

• Generally used by remote applications

• Uses Open Data (OData) Protocol Also known as: Astoria, ADO.NET Data Services, WCF Data Services

Data centric (REST) Web service

Data returned in AtomPub or JSON format

Metadata is available

Allows creation of service proxy

Strongly-typed access to data

Requests for collections may not return all items

Max 1,000 items returned per request

Need to check for continuation

Page 19: Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor - SPTec…

REST APIs

• URLs map to SharePoint resources

Example: ListData.svc/Products(2)/Category maps to the category

for the product with id == 2

• Protocol commands

$filter={simple predicate}

$expand={Entity}

$orderby={property}

$skip=n

$top=n

$metadata

Page 20: Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor - SPTec…

REST APIs (OData)

Page 21: Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor - SPTec…

Consuming Data via REST APIs

Page 22: Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor - SPTec…

Consuming Data via REST APIs

var context = new DemoDataContext(new Uri(

"http://localhost/sites/demo/_vti_bin/ListData.svc"));

context.Credentials = CredentialCache.DefaultCredentials;

var query = from detail in context.OrderDetails

where detail.UnitPrice < 100

select detail;

var queryCount = query.Count();

var details = new List<OrderDetailsItem>();

var dsquery = query as DataServiceQuery<OrderDetailsItem>;

var response = dsquery.Execute() as QueryOperationResponse<OrderDetailsItem>;

details.AddRange(response);

var token = response.GetContinuation();

while (token != null)

{

response = context.Execute(token);

details.AddRange(response);

token = response.GetContinuation();

}

Page 23: Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor - SPTec…

Consuming Data via REST APIs

var url = "http://localhost/sites/demo/_vti_bin/ListData.svc";

var context = new DemoProxy.DemoDataContext(new Uri(url));

context.Credentials = System.Net.CredentialCache.DefaultCredentials;

var products = from product in context.Products

where product.Category.Title == "Condiments" &&

product.UnitsInStock > 0

select product;

foreach (var product in products)

{

product.UnitsInStock += 1;

context.UpdateObject(product); // don’t forget this

}

context.SaveChanges();

Page 24: Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor - SPTec…

DEMO Using the REST APIs

Page 25: Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor - SPTec…

LINQ to SharePoint

• LINQ provider generates CAML for query Requires reference to Microsoft.SharePoint.Linq.dll

• Only available to server object model

• Queries are strongly-typed

• Entities created using SPMetal command-line utility Similar to SqlMetal in LINQ to SQL

Located in <System root>\bin

Basic usage

spmetal /web:<site url> /code:<file name>

Code generation can be customized via parameters XML file

http://msdn.microsoft.com/en-us/library/ee535056.aspx

Page 26: Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor - SPTec…

Consuming Data with LINQ to SharePoint

var url = "http://localhost/sites/demo";

var context = new SPNorthwind.SPNorthwindDataContext(url);

// context.Log = Console.Out;

var products = from product in context.Products

where product.Category.Title == "Condiments" &&

product.UnitsInStock > 0

select product;

foreach (var product in products)

{

product.UnitsInStock += 1;

}

context.SubmitChanges();

Page 27: Tutorial, Part 3: SharePoint 101: Jump-Starting the Developer by Rob Windsor - SPTec…

DEMO LINQ to SharePoint