Cross Site Collection List using OData and Business Connectivity Services

Body:

In the article I will walk through how to use OData, Business Connectivity Services to create a solution for cross site collection list scenarios

For the purpose of this article I created a Site Collection in my environment and named it “Shared” , full URL of this site collection is “https://team.contoso.local/sites/shared”, this site collection also contains a “Contacts” list named “Team Contacts”. Goal is to expose this list to other site collections so you have all the data in one central location and still accessible from other site collections as if the list was available locally within the site collection.

Add a web service reference to your BDC Model project in Visual Studio 2010, see image below

odata1

Next we will go ahead and add a BDC model to the project, see image below

odata2

Add an entity into your model by choosing the entity option from the toolbox and dragging it on to the design surface. Rename the entity to “Contacts”, add an identifier to the entity, name it “ID” and changed the data type to System.Int32

Using the BDC Method Details window add a finder method to the “Contacts” entity, this will create a “ReadList” method, next we need to change the data type of “Contacts” typedescriptor to use the OData entities generated by Visual Studio 2010 when we added the OData service reference. See image below

odata3

Set up additional typedescriptors, see image below

odata4

Next create a SpecificFinder method, add “Creator”, “Updater” and “Deleter” If you want to provide full CRUD capabilities.

At this point we are pretty much ready to wire up the entity service class, I have gone ahead and implemented all the CRUD methods. See the code from the entity service class below. Not a whole lot to explain, I’m using OData to perform CRUD operations against the “Team Contacts” list in the shared site collection

    1: public static IEnumerable<TeamContactsItem> ReadList()
    2: {
    3:     SharedSiteCollectionDataContext dc = new SharedSiteCollectionDataContext(new Uri("https://team.contoso.local/sites/shared/_vti_bin/listdata.svc"));
    4:     dc.Credentials = CredentialCache.DefaultNetworkCredentials;
    5:  
    6:     var contacts = from c in dc.TeamContacts
    7:                 orderby c.Id
    8:                 select c;
    9:     return contacts;
   10: }
   11:  
   12: public static TeamContactsItem ReadItem(int id)
   13: {
   14:     SharedSiteCollectionDataContext dc = new SharedSiteCollectionDataContext(new Uri("https://team.contoso.local/sites/shared/_vti_bin/listdata.svc"));
   15:     dc.Credentials = CredentialCache.DefaultNetworkCredentials;
   16:  
   17:     var contact = (from c in dc.TeamContacts
   18:                 where c.Id == id
   19:                 select c).FirstOrDefault();
   20:     return contact;
   21: }
   22:  
   23: public static TeamContactsItem Create(TeamContactsItem newContacts)
   24: {
   25:     SharedSiteCollectionDataContext dc = new SharedSiteCollectionDataContext(new Uri("https://team.contoso.local/sites/shared/_vti_bin/listdata.svc"));
   26:     dc.Credentials = CredentialCache.DefaultNetworkCredentials;
   27:  
   28:     dc.AddToTeamContacts(newContacts);
   29:     dc.SaveChanges();
   30:  
   31:     return newContacts;
   32: }
   33:  
   34: public static void Delete(int id)
   35: {
   36:     SharedSiteCollectionDataContext dc = new SharedSiteCollectionDataContext(new Uri("https://team.contoso.local/sites/shared/_vti_bin/listdata.svc"));
   37:     dc.Credentials = CredentialCache.DefaultNetworkCredentials;
   38:  
   39:     TeamContactsItem contactToDelete = (from c in dc.TeamContacts
   40:                               where c.Id == id
   41:                               select c).FirstOrDefault();
   42:  
   43:     if (contactToDelete != null)
   44:     {
   45:         dc.DeleteObject(contactToDelete);
   46:         dc.SaveChanges();
   47:     }
   48: }
   49:  
   50: public static void Update(TeamContactsItem contacts)
   51: {
   52:     SharedSiteCollectionDataContext dc = new SharedSiteCollectionDataContext(new Uri("https://team.contoso.local/sites/shared/_vti_bin/listdata.svc"));
   53:     dc.Credentials = CredentialCache.DefaultNetworkCredentials;
   54:  
   55:     //retrieve the contact to update
   56:     TeamContactsItem contactToUpdate = (from c in dc.TeamContacts
   57:                                         where c.Id == contacts.Id 
   58:                                         select c).FirstOrDefault();
   59:     if (contactToUpdate != null)
   60:     {
   61:         //set fields to update
   62:         contactToUpdate.FirstName = contacts.FirstName;
   63:         contactToUpdate.LastName = contacts.LastName;
   64:         contactToUpdate.HomePhone = contacts.HomePhone;
   65:         contactToUpdate.Address = contacts.Address;
   66:         contactToUpdate.BusinessPhone = contacts.BusinessPhone;
   67:         contactToUpdate.City = contacts.City;
   68:         contactToUpdate.Company = contacts.Company;
   69:         contactToUpdate.CountryRegion = contacts.CountryRegion;
   70:         contactToUpdate.EMailAddress = contacts.EMailAddress;
   71:         contactToUpdate.FaxNumber = contacts.FaxNumber;
   72:         contactToUpdate.FullName = contacts.FullName;
   73:         contactToUpdate.JobTitle = contacts.JobTitle;
   74:         contactToUpdate.MobileNumber = contacts.MobileNumber;
   75:         contactToUpdate.StateProvince = contacts.StateProvince;
   76:         contactToUpdate.WebPage = contacts.WebPage;
   77:         contactToUpdate.ZIPPostalCode = contacts.ZIPPostalCode;
   78:         
   79:         //update the entity
   80:         dc.UpdateObject(contactToUpdate);
   81:         dc.SaveChanges();
   82:     }
   83: }

 

Deploy the BCS solution to farm and create an external list called “Contacts” in root site collection “https://team.contoso.local”, I usually provide a site collection scoped feature  with a feature receiver that programmatically creates the external list when ever I use .NET connectivity to create my BCS entities.

End Result:

Image below shows “Team  Contacts” list in “Shared” Site Collection

odata5

Image below shows the external list “Contacts” created in root site collection, as you can see from the image there is full CRUD support and users can work with the contacts data same way they would if the “Contacts” list was available locally within the site collection, thanks to external list feature within BCS that provides the familiar list like user interface Smile

Odata6

 

Couple of things to keep in mind regarding working complex data types in BCS, see this article from BCS team https://blogs.msdn.com/b/bcs/archive/2010/02/10/working-with-complex-data-types-in-business-connectivity-services.aspx also same approach can be used to work around the data access limitation in Sandbox solution, only change would be to leverage secure store in .NET connectivity project

Hope that helps

Cheers,

</Ram>

Technorati Tags: SharePoint 2010,BCS

Published: 8/18/2011 9:37 AM

Attachments: https://www.spmcm.me/Blog/Lists/Posts/Attachments/41/odata1_2_281AE3DF.png
https://www.spmcm.me/Blog/Lists/Posts/Attachments/41/odata1_thumb_281AE3DF.png
https://www.spmcm.me/Blog/Lists/Posts/Attachments/41/odata2_2_281AE3DF.png
https://www.spmcm.me/Blog/Lists/Posts/Attachments/41/odata2_thumb_281AE3DF.png
https://www.spmcm.me/Blog/Lists/Posts/Attachments/41/odata3_4_1329616C.png
https://www.spmcm.me/Blog/Lists/Posts/Attachments/41/odata3_thumb_1_1329616C.png
https://www.spmcm.me/Blog/Lists/Posts/Attachments/41/odata4_2_1329616C.png
https://www.spmcm.me/Blog/Lists/Posts/Attachments/41/odata4_thumb_1329616C.png
https://www.spmcm.me/Blog/Lists/Posts/Attachments/41/odata5_4_1329616C.png
https://www.spmcm.me/Blog/Lists/Posts/Attachments/41/odata5_thumb_1_1329616C.png
https://www.spmcm.me/Blog/Lists/Posts/Attachments/41/Odata6_4_4116B424.png
https://www.spmcm.me/Blog/Lists/Posts/Attachments/41/Odata6_thumb_1_4116B424.png
https://www.spmcm.me/Blog/Lists/Posts/Attachments/41/wlEmoticon-smile_2_1329616C.png