Introduction
Lots of article demos are available for RIA services but most of them are based on one table without any relational constraint. However, most real-time applications revolve around data from multiple tables and CRUD operations against them. Let’s see one of the queries I received from a reader:
“My issue is, I have a sales invoice, and when using the Save button, I want to update the Sales master detail table which I can do from RIA, and after saving, I want to update the inventory table too. Is there an option where I can call the update inventory table using this entity?”
Basically, the above query seems to be involving RIA service operations with multiple tables. In this post, I am going to discuss about relational/hierarchical data and CRUD operations against them using RIA. It is time to add some more functionality to the SOI application.
Revisiting the SOI Demo (States of India)
The name of the app is explanatory enough. It involves state information and the cities associated with the states. The model diagram below shows the entity model definition with a one to many relationship. A detailed description about StatesOfIndia
(SOI) can be found in the following posts:

This post goes beyond traditional data operations over a single table with associations of data and CRUD operations over multiple entities related to each other.
Different Types of Data Models from the RIA Point of View
Although it looks like a long headed theory post, the concept of Data Models and RIA Framework implementation is important before proceeding over to the rest of the article. The RIA service framework provides three types of Data Model features to interact with the complicated data with relationships.
![image_thumb1_thumb[2] image_thumb1_thumb[2]](180646/image_thumb1_thumb2_thumb.png)
Depending on the type of the model you choose, the domain operations differ. Basically, we can always edit an entity without implementing any of the above models by using separate domain operations for the entity and sending the entity collection to the client by using IncludeAttribute
. However, consider the case above: the State
consisting of multiple cities, and a query to the State
not loading the city
collection on the client side. This is the default behaviour of Entity Framework’s Deferred Loading concept. We have to explicitly mention in the state
class to load the cities. In this post, I will demonstrate exactly the same, but it is worth knowing a little bit more about the above three models, and why and in which scenario we should follow the models.
Compositional Model | Inheritance Data Model | Data Projection /Presentation Model |
One to many | Entity derived from the base entity | Consolidated objects from multiple entities |
Parent Customer with multiple AddressDetail as descendents (State and City as in the above example, but does not make a good Composite model) | UrbanCustomer , RuralCustomer derived from the base Customer entity | Customer , AddressDetail , Address relationship (check with the model from MSDN) |
When the descendent entity does not make sense without the parent | | |
Data operation to the descendent entity (AddressDetail ) can be made by the parent (Customer ) entity only | Instead of exposing the derived entities to the client, the base Customer can be exposed and the data operation can be achieved by a polymorphic query | |
Attributes used [Composite] , [Include] | Attributes used [KnownType] | |
The implementation of a data model completely depends on the scenario. In the SOI app, City
can exist without the State
. However, an Address
/Invoice
does not exist without a Customer
/Person
for an ecommerce scenario, and the CRUD on Address
/Invoice
must be handled through the Customer
. Although explaining all these models with the same (State
/City
) scenario is difficult, I will try to cover each separately in future posts. So in this post, we will proceed with a simple association of entities spanning across multiple tables for CRUD operations.
The Problem Statement / Requirement
With my series of articles, I had demonstrated how to update, delete, and insert State
entities. You can find the link to those posts mentioned above in this article. It is obvious how to get the Cities while viewing or editing a State
. Unlike in RIA, in Silverlight, we cannot exactly replicate the deferred loading concept of Entity Framework, but we have an option to load cities by adding another operation to the domain context: LoadCity(int SateID)
.
Here, I am going to explain eager loading with a RIA service. On the SOI application, my requirement is simple:
“While navigating through States, the Cities of the respective States should be loaded, and while Editing or Adding a State, it should allow Adding one / multiple cities to the State entity.
Let's make some changes to our UI:

Implementation
The first step involves changing the DomainContext
Entity Metadata. As mentioned earlier, the State
containing the City
collection needs to be decorated with the Include
attribute. This attribute specifies that the association should be part of any code-generated client entity, and that any related entities should be included when serializing the results to the client. So in the StateMetadata
class (DomainService_SOI.Metadata.cs), we will add the following attribute to the Cities
member of the State
entity.
Add the Attribute to the Entity Metadata
[Include]
public EntityCollection<City> Cities { get; set; }
In the query method, you must ensure that the associated entities are actually loaded by using the Include
method on the query. This attribute can also be used to specify member projections. So we have to modify the existing query method or else create an additional query which will include the city
entity.
Change the Query in the Domain Service
public IQueryable<State> GetStatesWithCities()
{
return this.ObjectContext.States.Include("Cities");
}
Let's change the load query of the home page of the application which needs to call the newly added query.
LoadOperation<State> statesLoadOp =
dataContext.Load(dataContext.GetStatesWithCitiesQuery());
statesLoadOp.Completed += new EventHandler(statesLoadOp_Completed);
On debugging, you will find that the cities
are loaded along with the state
:

This is sufficient to create an association of the entities. Next, we will bind the Cities
collection to the control for CRUD operations.
Binding a Descendant to the Control
The SOI application intends to display all the cities
of a state
, where the user can read, edit, or delete a city
of a particular state
.

May be explaining the logic of the app will be like testing the reader’s patience, so I leave it to the reader to have a look at the application which is available live here and get an understanding of the flow of the application. The logic of data binding for the application looks like:

Steps 1 and 2 of data binding are covered in my earlier posts so we will proceed to Step 3 (assigning the Data Source to the ListBox
) and Step 4 (using the TextBox
to edit and update a City
).
Binding Cities to the ListBox

Assigning a TextBox to the ListBox’s Selected Item for Editing Cities

The Final Stroke
Well, a little bit of logic to submit the changes to the City
collection of the State
. On the final Ok button call, we need to identify whether the request is for a new City
or for update an existing City
. So my logic follows as below:
private void btnSaveNewCity_Click(object sender, RoutedEventArgs e)
{
State objState = (State)chldMainContainer.DataContext;
if (!_isNewCityMode)
{
System.Windows.Data.BindingExpression bexp =
txtNewCity.GetBindingExpression(TextBox.TextProperty);
bexp.UpdateSource();
}
else
{
City objCity = new City();
objCity.CityName = txtNewCity.Text;
objState.Cities.Add(objCity);
_isNewCityMode = false;
}
}
Where _isNewCityMode
is declared as a private
identifier for distinguishing between a New City
call and an Edit City
call.
Conclusion
This post aims to provide a complete picture of complex relational data models. We have seen the basic associations between entities. I haven’t examined the other types of operations (Composite
, Inherited
, Presentation
). I will try to explain those with suitable examples in future.
Source Code and Demo Link