In my previous post, I quickly walked through setting up, creating and deploying a BDC Model Project on to a local SharePoint Foundation 2010 system from within Visual Studio. Whilst it covered areas that others already have, I hoped to bring it all together in a step by step guide so that others in the same position I was may be able to avoid some of the nasty pitfalls in getting past that first hurdle. Now that we’ve got to this stage, I want to dive a little deeper into understanding how the various components fit together before I extend the project by referencing an external project. After all, the whole concept of BDC is to allow external LOB systems to be brought into your SharePoint arena so this should be a common scenario.
First of all, let’s take a look at what the BDC Model in our project is made up. When you create a BDC model project, a new explorer window becomes available to us – the BDC Explorer. This allows us to navigate through the various components of our model and make the necessary changes to build it into what we need. You’ll notice within your solution explorer as well that your BDC Model is a special folder that incorporates the following components:
The BDCModel.bdcm.diagram is simple an xml definition of the design layout of the Model diagram. To see how these solution items fit with the BDC components viewed in the BDC explorer, it is best we view the BDCModel1.bdcm file as Xml:
Excuse all the arrows but I’ve attempted to show how the elements within the actual Model relate to their components within both the BDC and Solution explorers. You can see from the xml that the parent object is the Model itself, naturally. This relates to the BDC Model view within your Business Data Connectivity Models page within the Application Services section of your SharePoint Central Administration.
A model comprises of a number LOB systems (in our case, just the one). These systems can either be a DotNet Assembly (connector), WCF or SQL. In our instance we are creating a DotNet connector. It is this system that appears under the “External Systems” section in your SharePoint Admin Application Services Page.
An External System can contain one or more Entities, referred to as External Content Types in the SharePoint Admin Application Services Page. In our case, this is Entity1. Note that this is not a direct mapping to our class, Entity1, but simply a description of the external content type. It is this component that defines the LOB system service class that defines the CRUD methods for interacting with our 3rd party system. Within each Method declaration, you can see the mapping to the method name (e.g. ReadList), and the mapping to the return parameter (IEnumerable<Entity1>). The BDC Model definition has to then dive even deeper though and describe the mapping to the type returned in the list (Entity1) and further more into the properties to be returned within that type. This is obviously quite a bit of manual work but I don’t expect the entities would change much, and if they did, only to include extra properties.
Now we can see how everything relates to solution items, BDC Model components and how they are reflected in your SharePoint Central Admin Service Application pages, we can start to create a BDC Project that reflects something close to a real-life scenario. Let’s take a common ERP scenario such as CRM. Most enterprises use some sort of CRM system to manage contacts and leads and yes, most of these systems offer some sort of connectivity to SharePoint but let’s assume we want to create our own connectivity through the BDC Model to surface Customer information. It is irrelevant how we retrieve this data – it could be directly from a SQL DB, via a WCF service, through an API, it doesn’t matter. All I am trying to demonstrate is that this happens in an external project that knows nothing of SharePoint at all.
For ease of reference, I’ll create my CRM Connector Library project in the same solution as my BDC Model but note this is not necessary. Obviously I am not going to replicate an entire CRM connector library so I’ll stick to a subset containing the following:
I have faked some data to provide a list of 4 customers. Before I reference this project in my BDC Model project, it makes sense if rename my necessary components so they are more relevant. Just be aware that the renaming of classes, namespaces and files needs to be done with caution as you must ensure you marry up any changes in all places. You may find it easier to begin a new BDC Model project from scratch. Either way, my new CRM BDC Model project is reflected in the screen shot of the solution explorer below:
To map the external entities (Customer, Address) across to my BDC Model, I have only been successful thus far in flattening the entire composite structure (i.e. Customer & Address) into the CustomerEntity class. When adding a Type descriptor into your BDC Model Return Parameters, whilst you can set the type to be one within your project, unless that type has an override ToString method, the property will not appear. If you have a encapsulated composite type, such as Address, the only way to surface this information is to flatten the Customer class properties, along with its Address, into the CustomerEntity class. I did try to add a second entity class, AddressEntity and then reference an instance of this type within CustomerEntity but my attempts to extract the data via the LOB Name property in the BDC Model resulted in an error. I would be interested to hear from anyone else who has looked into this and to learn if there is a best practice approach to this scenario.
For now though, my CustomerEntity class has all properties relating to both Customer and Address, and my new BDC Model is as below.
The three attributes worth noting when it comes to naming are as follows:
1. Type Descriptor: property name as appears in the list. This is the minimum and will be used for referencing the LOB property name and providing the default column name if none other is set.
2. LOB Name: property name as appears in the entity class you are referencing (i.e. Customer Entity). Must match exactly class name but need not match Type Descriptor.
3. Default Instance Name: name as should appear for column in SharePoint need not match LOB Name or Type Descriptor.
Because of changes to the Model name, feature name etc. you should not expect your previous external list to work. Because debugging ensures the retraction and deleting of previous models, if you did try to access the original external list you created, you will see the following error:
What I have also discovered is that, whilst the Visual Studio debugger will clean up your deployed BDC Model and External Content Type, it will not touch the LOB system within the Service Application Section. When I deploy my new CrmBdcModel, the previous BDCModel1 LOB system was still present.
We are almost finished but we have missed one last step. If you have deployed your project, with its new external reference, you will probably find that when you come to create your list, it errors when trying to view with an error alongs the lines of,
̋MethodInstance with Name ‘ReadList’ on Entity (External Content Type) with Name ‘CustomerEntity’ in Namespace ‘CrmBdcModel.CRMCustomerModel’ failed unexpectedly. The failure occurred in method ‘ReadList’ defined in class ‘CrmBdcModel.CRMCustomerModel.CustomerEntityService’ with the message ‘Could not load file or assembly ‘MyCRMConnector, Version=188.8.131.52, Culture=neutral, PublicKeyToken=ee909816b5cd7af9′ or one of its dependencies. The system cannot find the file specified.’
This is because we need to tell the package to include the external project reference. To do this, double click on the Package.package component
then click the “Advanced” tab at the bottom of the Package screen
Click Add and choose “Add Assembly from Project Output”
Select your external project and leave all other settings
You should now see your assembly added as part of your package
You can now hit F5 and the necessary project reference will be included in your solution and you can create your external list of customers successfully
In my next post on BDC Models in SharePoint Foundation 2010, I’ll walk through taking this project from the development environment and deploying on to a production SharePoint Foundation 2010 Server.