Developing with LINQ, REST and the Client Object Model in
Download
Report
Transcript Developing with LINQ, REST and the Client Object Model in
SESSION CODE: OFC322
Developing with LINQ, REST &
the New Client OM in
Microsoft SharePoint 2010
Hilton Giesenow
- The MOSS Show
Agenda
Accessing SharePoint data – then & now
List data model improvements in 2010
LINQ To SharePoint
Client Object Model
REST
Special thanks to…
3
Accessing SharePoint Data – circa 2007
Server Object Model
Weakly typed
Lots of XML
Long-winded
Non-standard
Non-relational
Garbage collection
4
Web Services
Weakly typed
TONS of XML
Long-winded
Non-standard
Non-relational
No WCF
Non standards-compliant
No flexibility
Overview of Data Technologies
REST APIs
Client OM
Web Services
Data Platform
Farm
Site
Web
List Data
Server OM
LINQ
5
External Lists
The Case Study - List Lookups
Lookups form relationships between lists
One-to-many
Many-to-many
Restrict / Cascade Deletes
6
List Data Model - Lists Joins and Projections
Query within and across lists:
Join lists using lookup columns
Lookup to multiple columns
7
Query
Result Set
Take Note: List Validation and Uniqueness
Excel-like validation formula
Can be specified on Columns and Lists
Example: =[Discount] < [Cost]
Column uniqueness constraint
8
Take Note: Query Throttling
Check query before execution
No index and count > limit
Joins > limit
Can turn throttling off using
SPQuery.RequestThrottleOverride
SPSiteDataQuery.RequestThrottleOverride
9
Relationships
Multi-Value Lookups
Data Integrity & Data Validation
Query Throttling
10
Querying SharePoint, circa 2007
<Query>
<Where>
<Or>
<Geq>
<FieldRef Name=“Field1" />
<Value Type=“Number">1500</Value>
</Geq>
<Leq>
<FieldRef Name=“Field2" />
<Value Type=“Number">500</Value>
</Leq>
</Or>
</Where>
</Query>
11
And the Code to Get There…
SPQuery query = new SPQuery();
StringBuilder sbQuery = new StringBuilder();
sbQuery.Append("<where>");
sbQuery.Append("<geq>");
sbQuery.Append("<fieldref name=\"" + fieldName1 + "\"/>");
sbQuery.Append("<value type=\"" + fieldType1 + "\">" + field
Value1 + "</value>");
sbQuery.Append("</geq>");
sbQuery.Append("</where>");
query.Query = sbQuery.ToString();
12
Joins in CAML
<Query>
<Where>
<And>
<BeginsWith>
<FieldRef Name="ContentTypeId" />
<Value Type="ContentTypeId">0x0100</Value>
</BeginsWith>
<Eq>
<FieldRef Name="ClientCity" />
<Value Type="Lookup">Durban</Value>
</Eq>
</And>
</Where>
</Query>
<ViewFields>
<FieldRef Name="Title" />
<FieldRef Name="ClientTitle" />
<FieldRef Name="BudgetHours" />
</ViewFields>
13
<ProjectedFields>
<Field Name="ClientTitle" Type="Lookup"
List="Client" ShowField="Title" />
<Field Name="ClientCity" Type="Lookup"
List="Client" ShowField="City" />
</ProjectedFields>
<Joins>
<Join Type="LEFT" ListAlias="Client">
<Eq>
<FieldRef Name="Client" RefType="ID" />
<FieldRef List="Client" Name="ID" />
</Eq>
</Join>
</Joins>
And the Code to Get There…
using (SPSite site = new SPSite(SPContext.Current.Site))
{
SPWeb web = site.RootWeb;
if (web != null)
{
SPList list = web.Lists["Parents"];
if (list != null)
{
SPQuery query = new SPQuery();
StringBuilder sbQuery = new StringBuilder();
sbQuery.Append("<where><eq>");
sbQuery.Append("<fieldref name="\"OtherChildren\"">");
sbQuery.Append("<value type="\"LookupMulti\"">My Other Child</value>");
sbQuery.Append("</fieldref></eq>");
query.Query = sbQuery.ToString();
StringBuilder sbJoins = new StringBuilder();
sbJoins.Append("<join listalias="\"OtherChildren\"" type="\"LEFT\"">");
sbJoins.Append("<eq>");
sbJoins.Append("<fieldref name="\"OtherChildren\"" reftype="\"ID\"">");
sbJoins.Append("<fieldref list="\"OtherChildren\"" name="\"ID\"">");
sbJoins.Append("</fieldref> ");
sbJoins.Append("</fieldref> ");
query.Joins = sbJoins.ToString();
StringBuilder sbProj = new StringBuilder();
sbProj.Append("<field list="\"OtherChildren\"" name="\"OtherChildrenNickname\"" showfield="\"Nickname\"" type="\"Lookup\"">");
query.ProjectedFields = sbProj.ToString();
StringBuilder sbView = new StringBuilder();
sbView.Append("<fieldref name="\"Title\"">");
sbView.Append("<fieldref name="\"OtherChildrenNickname\"">");
query.ViewFields = sbView.ToString();
14
if (!string.IsNullOrEmpty(query.Query))
{
SPListItemCollection matches = list.GetItems(query);
foreach (SPListItem match in matches)
{
Overview of Data Technologies
REST APIs
Client OM
Web Services
Data Platform
Farm
Site
Web
List Data
Server OM
LINQ
15
External Lists
LINQ
Local variable
type inference
Query
expressions
var CommonWords =
from w in wordOccurances
where w.Count > 2
select new { f.Name, w.Word, W.Count };
Lambda
expressions
=
var CommonWords
wordOccurances
.Where(w => w.Count > 2)
.Select(w => new {f.Name, w.Word, W.Count });
Extension
methods
16
Anonymous
types
Object
initializers
LinQ to…
17
LINQ Architecture
C# 3.0
VB 9.0
Others…
.NET Language Integrated Query
LINQ to
Objects
LINQ to
SQL
LINQ to
Entities
LINQ to
XML
LINQ to
SharePoint
<book>
<title/>
<author/>
<year/>
<price/>
</book>
Objects
18
XML
Relational
SharePoint
(CAML)
LINQ to SQL
from p in dataContext.Projects
where p.Client.City == “Durban"
select new
{
Name = p.Title,
ClientName = p.Client.Title,
Budget = p.BudgetHours
};
19
LINQ to SQL – It's Just SQL Underneath
SELECT
[t0].[Title] AS [Name],
[t1].[Title] AS [ClientName],
[t0].[BudgetHours] AS [Budget]
FROM
[dbo].[Projects] AS [t0]
INNER JOIN [dbo].[Clients] AS [t1] ON
[t1].[ID] = [t0].[ClientID]
WHERE
[t1].[City] = 'Durban'
20
LINQ to SharePoint
from p in dataContext.Projects
where p.Client.City == “Durban"
select new
{
Name = p.Title,
ClientName = p.Client.Title,
Budget = p.BudgetHours
};
21
LINQ to SharePoint – It's Just CAML Underneath
<Query>
<Where>
<And>
<BeginsWith>
<FieldRef Name="ContentTypeId" />
<Value Type="ContentTypeId">0x0100</Value>
</BeginsWith>
<Eq>
<FieldRef Name="ClientCity" />
<Value Type="Lookup">Durban</Value>
</Eq>
</And>
</Where>
</Query>
<ViewFields>
<FieldRef Name="Title" />
<FieldRef Name="ClientTitle" />
<FieldRef Name="BudgetHours" />
</ViewFields>
22
<ProjectedFields>
<Field Name="ClientTitle" Type="Lookup"
List="Client" ShowField="Title" />
<Field Name="ClientCity" Type="Lookup"
List="Client" ShowField="City" />
</ProjectedFields>
<Joins>
<Join Type="LEFT" ListAlias="Client">
<!--List Name: Clients-->
<Eq>
<FieldRef Name="Client" RefType="ID" />
<FieldRef List="Client" Name="ID" />
</Eq>
</Join>
</Joins>
Accessing Relational SharePoint Data using LINQ to SharePoint
23
LINQ to SharePoint – Some Limitations
Unsupported Queries & Limits
E.g. unsupported JOINS
Join Limits - MS recommends < 8
Query Throttling
2-stage queries
E.g. Aggregate, Distinct, Max, Min, Sum, SkipWhile
Cross-site-collections
Anonymous users
24
Overview / Summary
SQL Metal
Strong Typing
Relationships
Deferred Execution (& client-side queries)
Some limitations
25
Overview of Data Technologies
REST APIs
Client OM
Web Services
Data Platform
Farm
Site
Web
List Data
Server OM
LINQ
26
External Lists
Client OM
SharePoint Web
services
SharePoint
27
Client OM
End Client
Accessing SharePoint Data using the Client OM
28
Overview / Summary
Much easier than before (asmx only)
asmx web services still there if we need them
Not limited to defined API
Supports 3 client types
Managed Clients (sync)
Silverlight (async)
Javascript (async)
29
Overview of Data Technologies
REST APIs
Client OM
Web Services
Data Platform
Farm
Site
Web
List Data
Server OM
LINQ
30
External Lists
SOAP Vs. REST
i.e. What’s Wrong With SOAP?
The Envelope
Bloated
Not actually 100% interoperable
NOT fun from, e.g., Javascript
The RPC-style
Need to define entire interface
operations, params, return types
Leads to inconsistencies over time
Documentation
31
REST APIs
WCF is now supported!
What is Representational State Transfer (REST)?
And what is “OData”?
Strongly typed (depending on tools...)
WCF Data Services “Astoria”
32
33
REST (OData) APIs
Syntax:
/_vti_bin/ListData.svc/{Entity}[({identifier})]/[{Property}]
Example to get budget hours for Project #4:
/_vit_bin/ListData.svc/Projects(4)/BudgetHours
34
REST (OData) APIs
Syntax:
/_vti_bin/ListData.svc/{Entity}?$filter={simple predicate}
Example to get Projects for Clients in Chicago:
/_vit_bin/ListData.svc/Projects?$filter=Client/City eq ‘Durban'
35
REST (OData) APIs
Syntax:
/_vti_bin/ListData.svc/{Entity}?$expand={Entity}
Example to get a Project and its related Client:
/_vit_bin/ListData.svc/Projects?$expand=Client
36
REST (OData) APIs
$filter={simple predicate}
$expand={Entity}
$orderby={property}
$skip=n
$top=n
$metadata
See: http://msdn.microsoft.com/en-us/library/cc907912.aspx
37
38
Overview / Summary
Much easier than before (asmx only)
asmx web services still there if we need them
Not limited to defined API
Supports all client types
Strongly Typed
More Tooling
Open standards-based
39
Data Technologies in SharePoint 2010
SharePoint 2010 List Data Model
Relationships, Joins, and Data Integrity
LINQ to SharePoint, Client OM
Simple and integrated developer experience for list based Data
Applications
WCF & REST (OData) APIs
Simplified and standardized model for when you need it
40
Data Access Technologies - Decision Matrix
Client OM
On SharePoint Server
On Remote Computer
Site / List Objects
Traverse Relationships
Calling Pattern (Direct)
Calling Pattern (Callback)
41
REST /
ODATA
Server OM
LINQ to
SharePoint
Resources
The Moss Show - http://www.TheMossShow.com
http://sharepoint.microsoft.com
SharePoint Developer Center –
http://msdn.microsoft.com/sharepoint
SharePoint Tech Center –
http://technet.microsoft.com/sharepoint
Official SharePoint Team Blog –
http://blogs.msdn.com/sharepoint
42
Related Content
(WTB305) Panel Discussion: Ask the experts about SharePoint
(OFC423) Developing a BCS External Content Type with Visual Studio 2010
43
Resources
www.microsoft.com/teched
www.microsoft.com/learning
http://microsoft.com/technet
http://microsoft.com/msdn
Need more Information?
SMS [ Your Name ] and the word “Office” to 41491
44
© 2008 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries.
The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should
not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation. MICROSOFT MAKES NO WARRANTIES, EXPRESS,
IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.