Linq to SharePoint. Cross site collection queries

In this post I show how to execute Cross-SiteCollection queries in SharePoint using Linq to SharePoint.

Linq to SharePoint natively can only work in one Site Collection (SPSite). This limitation related to SPServerDataConnection object that provdes data connection to lists (or document libraries) in Linq to SharePoint. More specifically, the problem is with the SPServerDataConnection's constructor:

  1. public SPServerDataConnection(string url)
  2. {
  3.     if (SPContext.Current != null)
  4.     {
  5.         this.defaultSite = SPContext.Current.Site;
  6.         this.defaultWeb = (SPContext.Current.Web.Url == url) 
  7.             ? SPContext.Current.Web 
  8.             : this.defaultSite.OpenWeb(new Uri(url).PathAndQuery);
  9.     }
  10.     else
  11.     {
  12.         this.defaultSite = new SPSite(url);
  13.         this.defaultWeb = this.defaultSite.OpenWeb(new Uri(url).PathAndQuery);
  14.     }
  15.     if (!this.defaultWeb.Exists)
  16.     {
  17.         throw new ArgumentException(Resources.GetString("CannotFindWeb",
  18.                           new object[] { url }));
  19.     }
  20.     this.defaultWebUrl = this.defaultWeb.ServerRelativeUrl;
  21.     this.openedWebs = new Dictionary<string, SPWeb>();
  22.     this.openedWebs.Add(this.defaultWebUrl, this.defaultWeb);
  23. }

In other words, if SPContext is available we can't initialize data provider for other site collection. To overlimit this restriction we have set current context (SPContext.Current) to null and then SharePoint will initialize new SPSite object from URL.

Cross-SiteCollection Repository

To encapsulate Cross-SiteCollection queries into repository follow: add a new constructor that takes a boolean argumeny representing initialization for another site collection.

  1. protected BaseRepository(string listName, string webUrl, bool readOnly, bool crossSite)
  2. {
  3.     ReadOnly = readOnly;
  4.     ListName = listName;
  5.     WebUrl = webUrl;
  6.  
  7.     var ctx = SPContext.Current;
  8.     IsAnonymous = ctx != null && SPContext.Current.Web.CurrentUser == null;
  9.     if (crossSite)
  10.     {
  11.         var backupCtx = HttpContext.Current;
  12.         // Reset the context
  13.         HttpContext.Current = null;
  14.         // Initialize a new context and others
  15.         InitializeParameters();
  16.         HttpContext.Current = backupCtx;
  17.     }
  18.     else
  19.     {
  20.         InitializeParameters();
  21.     }
  22. }

Using

There is CrossSiteCollectionDataQuery webpart in my demo project that retrieves data from two lists located on two different site collections. CreateChildControls method in it is this:

  1. // Another site collection
  2. var repository1 = new EmployeeRepository("http://SharePointServer/linq"truetrue);
  3. var items1 = repository1.GetEntityCollection();
  4. foreach (var employee in items1)
  5. {
  6.     // Render information about an employee
  7.     RenderEmployeeInfo(employee);
  8. }
  9. Controls.Add(new LiteralControl("***<br/>"));
  10. // Current site collection
  11. var repository2 = new EmployeeRepository("http://SharePointServer/sites/asc"truefalse);
  12. var items2 = repository2.GetEntityCollection();
  13. foreach (var employee in items2)
  14. {
  15.     // Render information about an employee
  16.     RenderEmployeeInfo(employee);
  17. }

Result of code above looks like this:

Vitaly Zhukov

Vitaly Zhukov

SharePoint Architect, Developer, Technical Trainer, Microsoft MVP (Office Development). Above 15 years of total experience working with SharePoint, Dynamics CRM, Office 365, and Microsoft stack development.

You May Also Like

Provision Lists and Libraries with SPFx solution

Provision Lists and Libraries with SPFx solution

SharePoint. Drag-and-Drop File Uploading

SharePoint. Drag-and-Drop File Uploading

CSOM. Upload document

CSOM. Upload document

SharePoint List REST API. Part 2

SharePoint List REST API. Part 2

SharePoint Framework. Create Angular WebPart

SharePoint Framework. Create Angular WebPart

SharePoint List REST API. Part 1

SharePoint List REST API. Part 1

Project Server. CSOM + Custom Fields

Project Server. CSOM + Custom Fields

SharePoint 2010. Long time operation with updatable status

SharePoint 2010. Long time operation with updatable status

SharePoint. Getting Document Icon URL

SharePoint. Getting Document Icon URL

Linq to SharePoint. Repository pattern

Linq to SharePoint. Repository pattern

Linq to SharePoint vs Camlex.NET Performance Comparison

Linq to SharePoint vs Camlex.NET Performance Comparison

Linq to SharePoint. Part 5. Choice and MultiChoice fields

Linq to SharePoint. Part 5. Choice and MultiChoice fields

Linq to SharePoint. Part 4

Linq to SharePoint. Part 4

Linq to SharePoint. Part 3

Linq to SharePoint. Part 3

Linq to SharePoint. Part 2

Linq to SharePoint. Part 2

Linq to Sharepoint. Part 1

Linq to Sharepoint. Part 1