Using SPMetal for faster SharePoint development


Published on

This session will cover the ins and outs of SPMetal, a tool which ships with SharePoint 2010. SPMetal allows developers compile-time access to SharePoint lists, content types and columns. This allows for type-safe access to columns/fields on a SharePoint site. Additionally, developers can write LINQ queries against these lists using SPMetal which speeds up query writing tremendously. We will cover adding support for complex column types (Managed Metadata, Publishing HTML, etc) which aren’t supported by SPMetal out of the box. Lastly we will also touch upon performance considerations and other best practices when coding with SPMetal.

Published in: Technology
1 Like
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Using SPMetal for faster SharePoint development

  1. 1. SPMetalPranav Sharmahttp://pranavsharma.infoSenior SharePoint ConsultantPortal Solutionshttp://www.portalsolutions.netTwitter: @ePranav
  2. 2. What is SPMetal and LINQ?“SPMetal is a command-line tool that generates entity classes, which provide an object-oriented interface to the Microsoft SharePoint Foundation content databases. Theseclasses are primarily used in LINQ to SharePoint queries; but they are also used to add,delete, and change list items with concurrency conflict resolution. Finally, they can beused as an alternative to the regular SharePoint Foundation object model forreferencing content.The tool is included with SharePoint Foundation and is located in%ProgramFiles%Common FilesMicrosoft Sharedweb server extensions14BIN”Language-Integrated Query (LINQ) is a set of features that extends powerful querycapabilities to the language syntax of C# and VB. LINQ introduces standard, easily-learned patterns for querying and updating data, and the technology can be extended tosupport potentially any kind of data store” (MSDN)
  3. 3. Let’s create a sample list
  4. 4. Setting up SPMetal Create PreBuild.bat and save with encoding: Unicode (UTF-8 without signature) – codepage 65001 Include generated codefile in project Add project reference to Microsoft.SharePoint.Linq.dll Sign project using key file
  5. 5. Options (1 of 3)Option Value definition Example Commentsweb The complete, /web:http://ContosoServer/ Required. You can have port numbers in the server name; for absolute URL of Marketing example, /web:http://ContosoServer:5555/Marketing. the Web site Do not include the home page or any other page in the URL. whose data is modeled by the entity classes.code The relative or /code:MarketingSite.cs If this option is not used, the generated code is streamed to standard absolute path and output. file name of the If no file name extension is specified or the file name extension is not output file. either "cs" or "vb", the language option must be used. The file name (exclusive of the extension) is also used to form the beginning of the name of a class that derives fromDataContext; in this example the class is namedMarketingSiteDataContext. The derived class represents the lists and data of the whole Web site, so choose a file name that conveys that meaning. (You can override this naming behavior with an SPMetal Parameters XML file.)language The programming /language:csharp The only possible values are "csharp" and "vb". language of the If the value of the code option has either "cs" or "vb" as a file name generated code. extension, SPMetal can infer the language and thelanguage option is not needed.namespace The namespace /namespace:Contoso.TeamA If this option is not used, the generated code specifies no namespace that contains the ctivityReports and the compiled assembly treats the default namespace specified in entity class the properties of the Visual Studio project as the namespace of the declarations. generated classes.
  6. 6. Options (2 of 3)Option Value definition Example Commentsuseremoteapi No value. /useremoteapi This option signals that the value of the web parameter points to a server that is not the one on which SPMetal is running. One possible use for this parameter is to generate code against a Web site on an online deployment of SharePoint to which you intend to upload your solution as a sandboxed solution.user The user in whose context /user:Contosobob Use this option if you do not want SPMetal to run in SPMetal executes. your own context. Specify the domain.password The password for the user /password:$5U+ryz Use in conjunction with the user option. specified in theuser option.serialization Specifies whether objects /serialization:unidirectional The only possible values are "unidirectional" and that instantiate the "none". Specify "unidirectional" if you want the objects generated classes are to be serializable. SPMetal adds appropriate attributes serializable. from theSystem.Runtime.Serialization namespace to the class and property declarations and adds handlers for the Deserializing event. If this option is not used, "none" is assumed.parameters Identifies the path and name /parameters:MarketingSite.xml You typically will not reuse exactly the same parameters of an XML file that contains XML file for different Web sites, so name the file the overrides of SPMetal default same as the Web site. settings. For more information about the parameters file, see Overriding SPMetal Defaults by Using a Parameters XML File.
  7. 7. Options (3 of 3)<?xml version="1.0" encoding="utf-8"?><Web AccessModifier="Internal"xmlns=""> <ContentType Name="Contact" Class="Contact"> <Column Name="ContId" Member="ContactId" /> <Column Name="ContactName" Member="ContactName1" /> <Column Name="Category" Member="Cat" Type="String"/> <ExcludeColumn Name="HomeTelephone" /> </ContentType> <ExcludeContentType Name="Order"/> <List Name="Team Members" Type="TeamMember"> <ContentType Name="Item" Class="TeamMember" /> </List></Web>
  8. 8. LoggingUse the DataContext’s Log property to inspect underlying SPQueriesusing (var context = new Sp2010DataContext("http://sp2010")){ var contextLog = new StringBuilder(); context.Log = new StringWriter(contextLog); Console.WriteLine(contextLog);}
  9. 9. Iteratingforeach (var myItem in context.MyList){ Console.WriteLine(myItem.Title); Console.WriteLine(" ->" + myItem.MyColumnChoice); //Console.WriteLine(" ->" + myItem.MyColumnManagedMetadata);}QueryingConsole.WriteLine((from myItem in context.MyList where myItem.MyColumnChoice.Equals(MyColumnChoice.BarackObama) select myItem.Title). FirstOrDefault());
  10. 10. Complex field types (1 of 3)private TaxonomyFieldValue _myColumnManagedMetadata; [ColumnAttribute(Name = "MyColumnManagedMetadata", Storage ="_myColumnManagedMetadata", FieldType = “Taxonomy")]public TaxonomyFieldValue MyColumnManagedMetadata{ get { return _myColumnManagedMetadata; } set { if ((value != _myColumnManagedMetadata)) { this.OnPropertyChanging("MyColumnManagedMetadata", _myColumnManagedMetadata); _myColumnManagedMetadata = value; this.OnPropertyChanged("MyColumnManagedMetadata"); } }}
  11. 11. Complex field types (2 of 3)[CustomMapping(Columns = new String[] {"MyColumnManagedMetadata"})]public void MapFrom(object listItem){ var item = (SPListItem) listItem; this.MyColumnManagedMetadata = item["MyColumnManagedMetadata"] as TaxonomyFieldValue;} public void MapTo(object listItem) { var item = (SPListItem)listItem; item["MyColumnManagedMetadata"] = this.MyColumnManagedMetadata; }
  12. 12. Complex field types (3 of 3)public void Resolve(RefreshMode mode, object originalListItem, object databaseListItem){ var origItem = (SPListItem) originalListItem; var dbItem = (SPListItem) databaseListItem; var origValue = (TaxonomyFieldValue) origItem["MyColumnManagedMetadata"]; var dbValue = (TaxonomyFieldValue) dbItem["MyColumnManagedMetadata"]; if (mode == RefreshMode.KeepCurrentValues || (mode == RefreshMode.KeepChanges && MyColumnManagedMetadata != origValue)) { dbItem["MyColumnManagedMetadata"] = MyColumnManagedMetadata; } else if (mode == RefreshMode.OverwriteCurrentValues || (mode == RefreshMode.KeepChanges && MyColumnManagedMetadata == origValue && MyColumnManagedMetadata != dbValue)) { MyColumnManagedMetadata = dbValue; }}
  13. 13. Updatingforeach (var myItem in context.MyList){ switch (myItem.Title) { case “Choice 1": myItem.MyColumnChoice = MyColumnChoice.BarackObama; break; case “Choice 2": myItem.MyColumnChoice = MyColumnChoice.MittRomney; break; default: myItem.MyColumnChoice = MyColumnChoice.None; break; }}context.SubmitChanges();
  14. 14. Insertingvar newItem = new MyListItem { Title = "Choice 3", MyColumnChoice = "Donald Trump" };context.MyList.InsertOnSubmit(newItem);context.SubmitChanges();
  15. 15. When to use SPMetal? “While testing with a list of 45K items, SPQuery performed at 0.06s compared to SPMetal’s performance at 9.98s” – Pranav Sharma (See Resources for full article) When to use SPMetal?  For quick wins when low on time  For low usage applications where list size doesn’t cause performance concerns  For easily binding SharePoint queries to data grids and repeaters  For complex query writing (Ex: Multi-list Lookups)  For new SP developers to avoid run-time errors by catching them at compile-time
  16. 16. Resources SPMetal (MSDN) How to: Use SPMetal (MSDN) Overriding SPMetal Defaults by Using a Parameters XML File (MSDN) SPMetal and the Managed Metadata Column Large list performance: SPMetal vs. SPQuery
  17. 17. Questions? Don’t forget to fill out evaluations online Show the sponsors some lovePranav Sharmahttp://pranavsharma.infoSenior SharePoint ConsultantPortal Solutionshttp://www.portalsolutions.netTwitter: @ePranav