Best practices with LINQ to SharePoint

LINQ to SharePoint is powerful and provides an easy way to manage data in SharePoint's lists without writing CAML code.

With this new coding facility, we could forget that in fact we still use CAML queries, and so that they are some good practices. Without respect these practices, you wan write some dangerous code for system performances.

This post contains my 9 most important rules to respect with LINQ to SharePoint.

 

1: Always dispose the data context

It's really important to understand how work the data context and the LINQ provider for LINQ to SharePoint.

The LINQ to SharePoint connexion is init from the string URL argument when you're creating a new instance of the data context.

If you're watching the code executed to create the SharePoint connection, you can see the following code:

using (MySharePointDataContext dataContext = new MySharePointDataContext(SPContext.Current.Web.Url))

{

    //Your LINQ code here

}

2: Use good names for your entities

The entities of your data model must have a good name. You should rename your entities to have singular names.

For example, in SharePoint you have a list called "Products". SPMETAL.exe will generate an entity type called ProductsItem. You should rename it to have "Product" only.

To do that, you must specify a parameter input file to SPMETAL. You can found more information about this file here: https://msdn.microsoft.com/en-us/library/ee535056.aspx

To write this files could be a long job, so I recommend you to use tools to do that. Consult the last rule number 9 to get my tools recommendations.

3: Use "two stages" queries when it's necessary only and monitor your CAML generated code

When you're using LINQ to SharePoint, you could have the following error:

"The query uses unsupported elements, such as references to more than one list, or the projection of a complete entity by using EntityRef/EntitySet."

In fact, this error occurs because some LINQ operations could not execute a direct CAML transformation of the query. This kind of queries must execute first a CAML query, and after that a LINQ to objects transformation.

The MSDN documentation is clear about it:

"Some LINQ queries cannot be completely translated into CAML. However, however such queries can, in principle, run correctly because they can be executed in two stages. First, the LINQ to SharePoint provider translates as much of the query into CAML as it can and executes that query."

To correct this error, you should cut your queries in two stages to force the first query execution before the second one. To do that, you should for example transform the first IEnumerable<T> in a list thanks to ToList() method.

The list of operator concerned by this kind of queries is available here: https://msdn.microsoft.com/en-us/library/ee536585.aspx

One important thing with that is to understand when you really need to use ToList and when you don't need. Only if it's necessary (the previous error occured), you should not use ToList method between some LINQ queries. If you do that, you will have a huge number of data passed from the content database back to the front-end Web server. You should work with LAMBDA expressions and IEnumerable<T> objects all the time, and use ToList() method only in the end of your treatments.

During the development life cycle, you should monitor all the CAML code generated by developers LINQ to SharePoint queries. You must check that this queries are optimized to get the minimum quantity of data. To check that use the Log property of your DataContext to analyze all the CAML queries. More information here: https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.linq.datacontext.log.aspx

 

4: Don't use unsupported queries

Some queries are unsupported with LINQ to SharePoint, don't use it.

More information about unsupported queries: https://msdn.microsoft.com/en-us/library/ee536585.aspx

 

5: Always think about the number of data returned by your queries

Don't forget that you generate CAML code, with all the limitations of the SharePoint Lists and the CAML language. Don't forget that it's a bad practice to return more than 1 000 item in one query in CAML; it's also the case with LINQ to SharePoint. You must be really vigilant about that and always use the method Take(int limit) in your LINQ queries to limit the number of items passed  from the content database back to the front-end Web server.

Don't forget that another way to optimize your CAML queries is to limit the number of Fields that you want to return. With LINQ to SharePoint, this best practice is still true.

With LINQ to SharePoint, it's possible thanks to the "select new" operators. For example, if you're write the LINQ query  “select new { c.Name, c.ZipCode }”, this can be translated into CAML as a <ViewFields> tag with two <FieldRef> child elements.

 

6: Implement solutions if you want to execute LINQ to SharePoint code with elevated permissions

If you refer to the SPServerDataConnection class constructor in this article, you can see that the data context's connection uses the SPContext or opens a new site. You can not specify a specific SPWeb object to execute the queries, so you can not:

  • Open a SPSite with specific token id
  • Specify credentials
  • Use SPSecurity.RunWithElevatedPrivileges method has not effect when the url is the same of the current site

To resolve this issue, some people implement a "HttpContext hack" to change the SPContext.Current.Site and SPContext.Current.Web object with elevated versions.

More information about this method here: https://blogs.msdn.com/b/sowmyancs/archive/2010/09/19/linq-to-sharepoint-and-runwithelevatedprivileges.aspx

Be careful when you're using this method, changing the HttpContext static elements could have large impacts if your utilization is bad.

 

7: Use the SharePoint 2010 SP1 or August 2010 KB to work with anonymous access

With the RTM release of SharePoint 2010 (foundation or server),  you can't use LINQ to SharePoint with anonymous web site.

If you want to use LINQ to SharePoint in an anonymous web site (as Internet site), don't forget to install SP1 or the August 2010 specific KB available here:

• “Anonymous users cannot use Language Integrated Query (LINQ) to query data in Microsoft SharePoint Foundation 2010. Additionally, the anonymous users are prompted for user credentials when they use LINQ to query data.
https://support.microsoft.com/kb/2266423

 

8: Use a data access layer

Don't forget that LINQ to SharePoint provides the way to build query, but is not a pattern to manage all your data access methods in your solution. Like for all the web developments technologies, you need to implement a robust data access layer architecture when you want to use data from SharePoint.

The most common implementation of a DAL is the repository pattern. The Repository pattern is an application design pattern that provides a centralized, isolated data access layer.

You can see some good documentation about how to implement a repository pattern with LINQ to SharePoint here:

https://msdn.microsoft.com/en-us/library/ff798478.aspx

https://msdn.microsoft.com/en-us/library/ff798373.aspx

 

9: Optimize your developer workstation

To optimize the LINQ to SharePoint job on the development workstation, I recommend to use some tools: