Walkthrough: Sharing Entities between Multiple Domain Services
[ This document was written for WCF Services Version 1 Service Pack 2 and might not be up to date Please see Release Notes or Changelog for a list of changes since WCF RIA Services ]
In your Open Ria Services application, you may need to display data from a variety of data sources or expose an entity to more than one domain service. For example, an e-commerce Web site may need to integrate data from its order processing system with products from a third-party domain service. Open Ria Services enables this scenario by supporting references between entities from different DomainContext types. For more information on the nature and limitations of this feature, see the Shared Entities topic.
In this walkthrough, you will be shown two different ways of defining an association between entities in different domain context instances:
In the first part, the association is defined by adding code in the server project.
In the second part, the association is defined with code in the client project.
Both approaches to defining the association use the same code on the client to retrieve and display the data.
For illustrative purposes in this walkthrough, you will create two entity models and two domain services for exposing data in the AdventureWorksLT sample database. Typically, you would not create two entity models and two domain services to expose data from a single source. We are using this approach here to simplify the example while learning the technique that you can then use in more complicated scenarios that employ multiple data sources. For another example of displaying related data from a single data source, see Walkthrough: Displaying Related Data in a Silverlight Business Application.
Prerequisites
This and the other walkthroughs presented in the Open Ria Services documentation require several prerequisite programs, such as Visual Studio and the Silverlight Developer Runtime and SDK, be installed and configured properly, in addition to Open Ria Services and the Open Ria Services Toolkit. They also require installing and configuring SQL Server 2008 R2 Express with Advanced Services and installing the AdventureWorks OLTP and LT database.
Detailed instructions for the satisfaction of each of these prerequisites are provided by the topics within the Prerequisites for Open Ria Services node. Follow the instructions provided there before proceeding with this walkthrough to ensure that you encounter as few problems as possible when working through this Open Ria Services walkthroughs.
Creating a solution, the data models, and domain services
To set up a Open Ria Services Solution
In Visual Studio, create a new Open Ria Services project by selecting File, New, and then Project.
The New Project dialog box appears.
Select the Silverlight Application template from the Silverlight Templates and name the new project SharedEntityExample.
Click OK.
The New Silverlight Application dialog box appears.
Select the Enable Open Ria Services check box at the bottom of the window.
Click OK to create the solution.
To create two entity data models
In Solution Explorer, right-click the server project (SharedEntityExample.Web), select Add, and then select New Item.
The Add New Item dialog box appears.
Select Data from the list of Installed Templates on the left, and then select the ADO.NET Entity Data Model template.
Name the new file SalesModel.edmx and click Add.
The Entity Data Model Wizard appears.
In the Choose Model Contents screen, select Generate from database and then click Next.
In the Choose Your Data Connection screen, create a data connection to the AdventureWorksLT database.
If the AdventureWorksLT database does not appear in the dropdown list, click on New Connection, select the correct Server name, and then select the AdventureWorksLT data base from the drop-down menu in the Connect to a database box lower down in the window. Select Test Connection button to make sure the database is accessible and click OK.
Make sure that the Save entity connection settings in Web.Config as check box is selected when you are returned to the Entity Data Model Wizard and change the value of the entity connection settings to Sales_DataEntities.
Click Next.
In the Choose Your Database Objects screen, select the SalesOrderHeader table.
Click Finish.
The entity model is created for the table.
Repeat the previous steps in this section to create another Entity Data Model for the AdventureWorksLT database, but name it CustomerModel.edmx, change the value of the entity connection setting in Web.config to Customer_DataEntities, and select the Customer (SalesLT) table.
Build the solution.
Open the code file for the Sales entity model, and notice that the SalesOrderHeader class has a CustomerID property. You will use this property to associate SalesOrderHeader and Customer.
To create the domain services
Right-click the SharedEntityExample.Web server project, select Add and New Item.
In the list of categories, select Web and then select the Domain Service Class template.
Name the class SalesDomainService.cs (or SalesDomainService.vb).
Click Add.
The Add New Domain Service Class dialog box appears.
Make sure the Enable client access check box is selected.
From the Available DataContext/ObjectContext classes list, select Sales_DataEntities (Entity Framework) data context object.
[!TIP] If you gave your data connection a different name when creating the entity model, select the data context object that contains the SalesOrderHeader entity.
Under Entities, select the SalesOrderHeader entity check box.
Click OK.
This generates the domain service class.
Repeat the previous steps in this section to create another domain service, but name it CustomerDomainService.cs (or CustomerDomainService.vb), select the Customer_DataEntities data context object, and select the Customer entity check box.
Build the solution.
In the client project, in the Generated_Code folder, open the generated code SharedEntityExample.Web.g.cs file (you will have to show all to see this file which is hidden by default) and notice that there is a SalesDomainContext and a CustomerDomainContext. You will use both domain context objects to load the associated data.
Close the generated code file.
Defining the association with code in the server project
You currently have two separate entity models and two domain services that each exposes one entity. You could load data from either entity separately by calling the appropriate domain service. But to load data that is a combination of data from both of the entities, you must define the relationship between these entities. The following steps show how to define that relationship in the server project.
To define the association in the server project
Right-click the server project, select Add and New Item.
In the list of categories, select Web and then select the Class template.
Name the class SalesOrderHeader.cs (or SalesOrderHeader.vb) and then click Add.
In the SalesOrderHeader class file, add the partial keyword to the class declaration.
Add a property named Customer that returns an object of the Customer type.
Add a using (or Imports) statements for the OpenRiaServices and System.ComponentModel.DataAnnotations namespaces.
Add the ExternalReferenceAttribute attribute to the Customer property.
Build the solution.
In the client project, in the Generated_Code folder, open the generated code file and notice that the SalesOrderHeader class now contains a Customer property with the ExternalReferenceAttribute and AssociationAttribute attributes.
Close the generated code file.
Loading the data from both entities
Properties that reference an entity from another domain context will be null until the referenced entity is loaded in its original domain context. The referenced entity is not automatically loaded. You must load the entity through its origin domain context before accessing the cross-referenced entity.
To load the data from both entities
In the client project, open the MainPage.xaml file.
From the Toolbox, drag a DataGrid control to within the Grid element.
An XML namespace and references to Data assemblies are added.
Name DataGridSalesGrid and define columns to display the combined data as shown in the following XAML.
Open the code-behind file MainPage.xaml.cs (or MainPage.xaml.vb).
Add a using (or Imports) statement for the SharedEntityExample.Web namespace and the OpenRiaServices.Client namespace.
Create variables for instances of the SalesDomainContext and CustomerDomainContext.
In the constructor, add a reference between the domain context objects by calling the AddReference method, load each entity by calling the Load method, and set the sales entities to the ItemsSource of the DataGrid.
Run the solution.
You will see a DataGrid instance that displays data from two entities in two separate entity models and domain services.
Defining the association with code in the client project
You can also define the association between the entities on the client, without having to add any code to the server project. This approach is better if you preferable not to introduce a new property in the server project whose only purpose is to achieve the client objective of displaying the data jointly.
To define the association with code in the client project
In the server project, delete (or comment out) the entire SalesOrderHeader.cs (or SalesOrderHeader.vb) file that you previously added.
Build the solution so that the generated code file no longer has a Customer property on the SalesOrderHeader object.
In the client project, add a new Class file named SalesOrderHeader.cs (or SalesOrderHeader.vb).
In the SalesOrderHeader class file, add the partial keyword to the class declaration, and change the namespace to SharedEntityExample.Web. (If you are using Visual Basic, you can specify the Web namespace by using the Namespace statement.)
This class extends the class in the generated code file. The generated entity class has the namespace from the server project.
Add a using (or Imports for Visual Basic) statement for the OpenRiaServices, OpenRiaServices.Client, and System.ComponentModel.DataAnnotations namespaces.
To establish the association, define the Customer property or the SalesOrderHeader class and mark it with the ExternalReferenceAttribute and AssociationAttribute attributes as shown in the following code sample.
Hit F5 to run the solution.
The DataGrid instance that displays data shared out from each of the entities in the two separate entity models in their respective domain services should now display in the browser.
Last updated