Click here to Skip to main content
Click here to Skip to main content

Performing CRUD operations on Relational Data (Multiple Tables) Using RIA in Silverlight 4

By , 13 Apr 2011
 

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:

RIA Service,Silverlight 4.0,Entity Framework,RIA Mutiple Table,Relational Data RIA

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 Modesl 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]

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 on 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 can not 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:

RIA Service,Silverlight 4.0,Entity Framework,RIA Mutiple Table,Relational Data RIA

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 the load query of the home page of the application which need to call the newly added query.

//Use LoadOperation method to Populate the Entity Collection 
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:

RIA Service,Silverlight 4.0,Entity Framework,RIA Mutiple Table,Relational Data RIA

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.

RIA Service,Silverlight 4.0,Entity Framework,RIA Mutiple Table,Relational Data RIA

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:

RIA Service,Silverlight 4.0,Entity Framework,RIA Mutiple Table,Relational Data RIA

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

RIA Service,Silverlight 4.0,Entity Framework,RIA Mutiple Table,Relational Data RIA

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

RIA Service,Silverlight 4.0,Entity Framework,RIA Mutiple Table,Relational Data RIA

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 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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Manas_Patnaik
Software Developer (Senior) Infosys
India India
Member
Nothing special .. I like challenges and love my critics.
 
Associate Consultant | Microsoft | Bangalore | India

Blog : http://manaspatnaik.com/blog

Twitter@manas_patnaik

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionBroken links!!!memberMember 165621426 Sep '11 - 9:15 
Hmmmm... I believe you should check and update your links
otherwise simply remove this article...
All the links displayed above are broken!!
 
HTTP Error 404.0 - Not Found :(
AnswerRe: Broken links!!!memberManas_Patnaik27 Sep '11 - 9:43 
Oops Sorry ,my domain host was down by the time you checked .
Its upright now.
 
Thanks.
Manas Patnaik
www.manaspatnaik.com/blog
Twitter - @manas_patnaik

GeneralSelecting only the first value from collectionmembersamrules8 Jun '11 - 3:30 
Hi,
 
my problem is quite similar to yours, the only difference is,
 
I have a common context for Person which contains tables PersonRecord and PersonPhotoes.
 
Now one Person can have many photoes so its one to many relationship. Now there is page where I need to show person information and his default image(which is the first image in PersonPhotoes table) so I need to display the first Image stored in table for that Person.
 
I have a Image control now I am confused how to select first Image from the collection of Images and bind it to Image control.
So not able to bind my Image Source to it, following is the Image control in Xaml
 
<Image x:Name="rectFaceImage" Margin="4,21,4,4" d:LayoutOverrides="GridBox" Source="{Binding Path=What should be here?????????}"/>
 

I hope I am clear with my problem. Thanks in advance
Regards
Sumit Gupta
GeneralEdit master and insert detailsmemberMichael Pröpster31 May '11 - 4:59 
Hi,
has anyone ever managed to do something like this:
 
var state = DomainContext.States.First();
state.Name = "sadfgh";
state.Cities.Add(new City(){ Name = "kjsdhf"});
DomainContext.SubmitChanges();
 
I'm asking because I can do all kind of CRUDs in one transaction except "Edit master and insert details"
 
Michael
GeneralRe: Edit master and insert detailsmemberMichael Pröpster3 Jul '11 - 21:05 
Does no one have an answer?
GeneralRe: Edit master and insert detailsmemberManas_Patnaik5 Jul '11 - 3:03 
Hello Michael
 
Sorry for late reply.
 

var state = DomainContext.States.First();
state.Name = "sadfgh";
state.Cities.Add(new City(){ Name = "kjsdhf"});
DomainContext.SubmitChanges();

 
You can always do updation with above code snippet .If you can follow the SOI app source it does exactly the same.It creates a state object and pass it to Child Modal popup page where the user edit state Properties as well add new cities.
 
So No problem at all if you follow above approach.
 
Thanks
Manas
Manas Patnaik
www.manaspatnaik.com/blog
Twitter - @manas_patnaik

GeneralInserting NEWmemberMember 66434315 May '11 - 17:07 
Hi,
 
How about saving data to multiple tables. The retrieving is not so hard given its just decorating with a single Include and changing an IQueryable. Could you kindly give an example of saving to two or three related tables say Patient [PatientID,Name...] and PatientAllergies[ID,PatientId,Allergy,Comment..]. An RIA Services MVVM example would really help. What your article shows is more of retrieving not inserting new records to multiple tables.
 
Thanks.
 
Francis
GeneralRe: Inserting NEWmemberManas_Patnaik20 May '11 - 2:05 
Hello Francis
I guess you missed the portion where it does save the releted entities into database.The State is having Cities in a different tables with relationship .Please download the the latest code available .
 
yeah this is not based on MVVM , I will come up with multiple patterns/Arch. for e.g MVVM,PRISM with same example scenario when ever i get time .
 
Thanks for commenting.
 
Thanks
Manas Patnaik
www.manaspatnaik.com/blog
Twitter - @manas_patnaik

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130523.1 | Last Updated 13 Apr 2011
Article Copyright 2011 by Manas_Patnaik
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid