CRUD Operations on Relational Data (Multiple table) using RIA with Silverlight 4

Relational/Hierarchical data and CRUD operation against them using RIA Service with a real time example.


Introduction

Many 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 check one of the queries I received from a reader.

"My issue is. like i have sales Invoice On save button I want to Update Sales master detail table which i can do from ria & after saving i want to update inventory table too. Is there any option i can call update inventory table using this entity."

Basically the above query seems to involve RIA service operation with multiple table. Well I am going to discuss this post about Relational/Hierarchical data and CRUD operation against them using RIA. So it's time to add some more functionality to the SOI application.

Source Code and Demo Link

Hosted Application : Live Sample

Source Code : StatesOfIndia_RelData.zip 

Revisiting the SOI Demo (States Of India)

The name of the app is explanatory enough. It involved the State Information and the Cities associated with the State.The below model diagram shows Entity model definition with a one to many relationship. A detailed description of the SatatesOfIndia (SOI) can be found in the following posts.

image_thumb.png

This post goes beyond traditional data operation over a single table with association of data and CRUD operations over the multiple entities related to each other.

Different Types of Data Model from RIA Point of View

Although it looks like a long headed theory post but the concept of Data Model and RIA Framework implementation is important before proceeding over the rest of this article.The RIA service framework provides 3 types of Data Model features to interact with complicated data with relationship.

image_thumb1_thumb2_thumb.png

Depending on the type of model you choose the domain operations differs. 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 multiple cities, query to State does not load the city collection to the client side. This is the default behaviour of the Entity Framework's Deferred Loading concept, We have to mention explicitly in the state class to load the Cities. In this post, I will demonstrate exactly that, but it is worth knowing a little bit more about above 3models, why and on which scenario, we should follow above model.

Compositional Model Inheritance Data Model Data Projection /Presentation Model
One to many Entity Derived from base Entity Consolidated objects from multiple entities
Parent Customer with multiple AddressDetail as  descendent
(State and City as in above example also but does not make a sincere composite model)
UrbanCustomer,RuralCustomer derived from base Customer Entity Customer,AddressDetail,Address relationship
(Check with the Model from MSDN),
when the descendent entity does not make sense with out 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 data operation can be achieved by polymorphic Query
Attributes used [Composite],[Include] Attributes used [KnownType]

The implementation of a data model completely depends on the scenario; in the SOI app of State.City for example a city can exist without a state. However, an address/Invoice does not exist without a customer/person for a given ecommerce scenario and the CRUD on address/Invoice must be handled through Customer.
Although explaining all these models with same (State/City) scenario is difficult, I will try to cover each separately in future posts. So in this we will proceed with a simple association of entities spanning across multiple tables for CRUD operation.

The Problem Statement / Requirement

With earlier series of articles I had demonstrated how to update, delete and Insert State entities. You can find the link to those posts with links above in this article. It's obvious to get the Cities while viewing or editing a state. As in RIA Silverlight we can't replicate the exact deferred loading concept of Entity Framework but we have an option to load the cities by adding another operation to domain contextLoadCity(int SateID).

Here I am going to explain the eager loading with RIA service.

Focusing to the SOI application, my requirement is simple

"While Navigating through the State the Cities of 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 changes to our UI:

image_thumb_3.png

Implementation

The First Step involves changing the DomainContext Entity Metadata; as mentioned earlier the state containing the City collection needs to be decorated with Include attribute.This attribute specifies that the association should be part of any code-generated client entities, and that any related entities should be included when serializing results to the client. So in the StateMetadata class (DomainService_SOI.Metadata.cs) we will add the following attribute to the Cities member of State entity.

Add the Attribute to the Entity Metadata:

  1. [Include]
  2. public EntityCollection<City> Cities { getset; }


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 have to create an additional query which will include the city entity.

Change the Query in Domain Service:

  1. public IQueryable<State> GetStatesWithCities()
  2. {
  3. return this.ObjectContext.States.Include("Cities");
  4. }


Let's change the load query of the Home Page of the application which we need to call the newly added query.

  1. //Use LoadOperation method to Populate the Entity Collection
  2. LoadOperation<State> statesLoadOp = dataContext.Load(dataContext.GetStatesWithCitiesQuery());
  3. statesLoadOp.Completed += new EventHandler(statesLoadOp_Completed);


On Debugging you will find the cities are loaded along with the state

image_thumb_4.png

This much is sufficient to create an association of entities. Next we will bind the cities collection to the control for CRUD operations.

Binding descendant to control

As the SOI application intends to display all the cities of the cities of a State, where the user can read, edit or delete a city to the particular state .

SNAGHTML1cade08_thumb.png

May be explaining the logic of the app will be like testing the reader's patience so I left it to the reader to have a look at the application Live here and have a understanding of the flow of the application.The logic of data binding for the application follows some how is like below figure.

image_thumb_5.png

Step1 and Step2 of data binding are covered with my earlier posts so we will proceed with Step3 (Assigning Data Source to List Box) and Step 4 (Using TextBox to edit and updating the City).

Binding Cities to the List Box:

SNAGHTML1d96541_thumb.png

Assigning TextBox to the ListBox's selected item for Editing Cities

SNAGHTML1f49fd1_thumb.png

The Final Stroke

Well a little bit of of logic to submit the changes to the City Collection of the State. On the final Ok button call  we need to identify weather the request is for a new City or Update of a existing City. So my logic follows as below:

  1. private void btnSaveNewCity_Click(object sender, RoutedEventArgs e)
  2. {
  3. State objState = (State)chldMainContainer.DataContext;
  4. if (!_isNewCityMode)
  5. {
  6. System.Windows.Data.BindingExpression bexp = txtNewCity.GetBindingExpression(TextBox.TextProperty);
  7. bexp.UpdateSource();
  8. }
  9. else
  10. {
  11. City objCity = new City();
  12. objCity.CityName = txtNewCity.Text;
  13. objState.Cities.Add(objCity);
  14. _isNewCityMode = false;
  15. }
  16. }

Where as the _isNewCityMode is declared as a private identifier to distingusih betwen a NewCity call or Edit of existing city.

Conclusion

This intention of this post is to provide a complete picture for complex relation data model. Well here we have seen the basic association between entities. I haven't touched the other ways of operations (Composite, Inherited, Presentation). I will try to explain those with suitable examples in the future.

Source Code and Demo Link

Hosted Application : Live Sample

Source Code : StatesOfIndia_RelData.zip

erver'>