Business Apps Example for Silverlight 3 RTM and .NET RIA Services July Update: Part 17: Evolving an Application

More from my Mix09 talk “building business applications with Silverlight 3”.  So far in this series we have looked at how to build out an new application using Silverlight 3 and .NET RIA Services… but now let’s look at how to evolve an existing SL3\RIA Services application… after all, for most of us that is our day-to-day jobs.  It is rare that we get to start with a green field application where we have full control.  Being able to deal with maintenance of an application takes a framework from being a cool demo toy to being an important tool!

For the context, you can watch the original  video of the full session  and catch up on the Full series

The demo requires (all 100% free and always free):

  1. VS2008 SP1 (Which includes Sql Express 2008)
  2. Silverlight 3 RTM
  3. .NET RIA Services July '09 Preview

Also, download the full demo files .

For this part, we will look at to interesting evolutions of the standard SuperEmployee app we have been building… The first is adding a new column to the table we have been working with and the second is to add a whole new table with additional data associated with each SuperEmployee.

A fair bit of the details of how the evolution workflow is accomplished is dependent on what DAL you use.  Because .NET RIA Services is DAL agonistic, this part of the evolution story can change a bit.  For this walkthrough I will show the story with Entity Framework and will leave it as an exercise for the reader to map it to your own DAL.

Adding a new Column

Ever since I cooked up the SuperEmployee schema 6 months ago I felt that it was really missing the most important aspect of being a super hero. That is knowing what his or her power is.  I mean, i have to know their super power to hire them right?  So let’s look at adding “Superpower” to the database.

Let’s open nortwind.mdf from the app_data directory and select Open Table Definition


Then add a new column called “SuperPower” and set it type to be nvarchar(MAX)


OK – we have the database scheme updated, now we need to update our model.  To do that open northwind.edmx and select “Update Model from Database”


Select Refresh


And we see our model is updated!


Now, simply build and we can access this new property from the web server in the DomainService if we needed to write some application logic that deals with it or we can access it directly from the client.


To start with, let’s add SuperPower to the list of fields the DataForm is handling for us…  This is just an update to the DataForm we talked about way back in Part 2: Rich Data Query

    <TextBox Text="{Binding SuperPower, Mode=TwoWay}" />

And of course the display works great


But I can now add a value to several SuperHeros and hit submit and see the values reflected in the database.


Now let’s add just a bit of validation to our new member.. In the SuperEmployeeDomainService.metadata.cs file add

    ErrorMessage = "Superpower's should be between 3 and 25 characters long")]
public string SuperPower;

build and run and we get get validation!


Let’s roll back to our Astoria service and our WinForm client from Part 5… what do we need to do to update those?  Well, not much.  The Astoria service is all dynamically generated based on the model and the DataGridView is also dynamic in this case, so all we need to do is update the service reference and we are good to go!


And the app runs great… an easy way to enter lots of data quickly..


What I showed so far is how easy it is to evolve your entity to have an addition field.  Let’s now look at adding a whole new entity.

Adding a New Associated Entity

For this example, i’ll add some contact information for the SuperHero agent so that we can get up with the SuperHero we decide to hire.   The first step is to add a table to our database to store the contact information


Then we need to associate it with the SuperEmployees table via an foreign key. 


Now we can update our Entity Framework model


We want to select the new Contact class


And update our SuperEmployee class to get the FK for the Contact


That gives us this model


do a full build and everything should be good.

Now let’s integrate the Contact table into our app. 

First we need to add the logic to our DomainService. 

   1: public IQueryable<SuperEmployee> GetSuperEmployees()
   2: {
   3:     return this.Context.SuperEmployeeSet
   4:                .Include("Contact")
   5:                .Where(emp=>emp.Issues>100)
   6:                .OrderBy(emp=>emp.EmployeeID);
   7: }

Notice in line 4, we told EF to include the associated Contact item when we pull each SuperEmployee from the database.

Now in SuperEmployeeMetadata.cs we need to add some metadata to tell RIA Services to include the contact information in data it sends to the client

public Contact Contact;

Now, we may want to edit this contact information, so let’s add methods to the DomainService to add new and update our Contact entity.

public void InsertContact(Contact contact)
public void UpdateContact(Contact currentContact)

Great.  The server side is done, now let’s go to the client..  Here what I want to do is add some UI to the details dataform to show the contact information.

Inside the DataForm in Home.xaml add a button to edit the contact information.

<Button Content="Edit Contact Information..." 
        Width="205" Height="28"
        Margin="15,10,0,0" HorizontalAlignment="Left"
        Click="EditContact_Click" >


And we need to handle the click event.  Here we create a ChildWindow to display a form to view\edit the contact information.

private void EditContact_Click(object sender, RoutedEventArgs e)
    var emp = dataForm1.CurrentItem as SuperEmployee;
    if (emp.Contact == null)
        emp.Contact = new Contact();
    var w = new EditContactWindow(emp.Contact);
    w.Closed += EditContact_Closed;
void EditContact_Closed(object sender, EventArgs e)
    var win = sender as EditContactWindow;
    var emp = dataForm1.CurrentItem as SuperEmployee;
    if (win.DialogResult == true)
        emp.Contact = win.Contact;

Add a new ChildWindow and call it EditContactWindow().  In the codebehind set it up in code behind. 

public partial class EditContactWindow : ChildWindow
    public Contact Contact;
    public EditContactWindow(Contact contact)
        Contact = contact;
        this.LayoutRoot.DataContext = Contact; 
    private void OKButton_Click(object sender, RoutedEventArgs e)
        this.DialogResult = true;
    private void CancelButton_Click(object sender, RoutedEventArgs e)
        this.DialogResult = false;

And the Xaml is simply a DataForm to display the results:

<dataFormToolkit:DataForm   x:Name="dataform1" CurrentItem="{Binding}">
                    <TextBox Text="{Binding ContactName, Mode=TwoWay}" />
                    <TextBox Text="{Binding ContactTitle, Mode=TwoWay}" />
                    <TextBox Text="{Binding Address, Mode=TwoWay}" />
                    <TextBox Text="{Binding City, Mode=TwoWay}" />
                    <TextBox Text="{Binding Region, Mode=TwoWay}" />
                    <TextBox Text="{Binding PostalCode, Mode=TwoWay}" />
                    <TextBox Text="{Binding Phone, Mode=TwoWay}" />

And it looks great!


Notice, back on the server in SuperEmployeeDomainService.metadata.cs, i did give it some metadata to control how the Contact is displayed.  This is where I would put validation as well. 

public partial class Contact
    internal sealed class ContactMetadata
        // Metadata classes are not meant to be instantiated.
        private ContactMetadata()
        public object ContactName;
        [Display(Name = "Title")]
        public object ContactTitle;
        public object Address;
        public object City;
        [Display(Name = "State")]
        public object Region;
        [Display(Name = "Zip Code")]
        public object PostalCode;
        public object Phone;

We are done!

In this part we looked at how to incrementally evolve a RIA Services + Silverlight application.  I showed how to add a new column to an existing table and how to add a whole new table.


Comments (26)

  1. BenHayat says:

    Brad, this thing is just keep getting better and better. I’d like to make a request for a sample where it involves with Hierarchy data and where the child data affects the parent. Here is a simple case for your data.

    Imagine, every time this Superhero employee answers a questions, she gets some points. So, we need to add another table that is a child to employee which shows the answer she gave and points she got.

    Then as the child gets added, the SuperEmploee table  needs to have another field (Total points) where the points from the child tables gets added to. Or vice versa, if a points are deleted, the total points gets decremented.

    This is a common case in LoB where you have an order table and Line items, but the order keeps track of total sales, net, tax and number of lines, as each line gets added or deleted.

    As these scenarios gets explored, it will show how SL & RIA are really capable of building real business applications. These are great and very useful series you’re doing to guide developers how to take on Business Apps with SL.



  2. Steve says:

    I’d like to see a unit of work with optimistic concurrency.

    User A get’s the data, meanwhile User B alters that same data and commits changes. Then User A commits.

    I think this is a common scenario in a disconnected application that needs to be handled.

    Great work – good series  🙂

  3. BenHayat says:

    Brad, I see one important step that’s missing in two sections of article.

    When you added a new field (SuperPower) to the SuperEmployee and updated the EDMX file or when you added the contact file to your EDMX file, you said "do a full build and everything should be good", however a build does not add the new field or file to the DomainService that already exist. This is one very important step missing, because how do you get DomainService to generate/add these new entities?

    I went back & forth and don’t see how a build adds those in.


  4. BenHayat says:

    The only way that I’ve been able to add new entities to my existing DS, is to create a new DS, go through the wizard to create a new entity (with metadata class), then I have to go manually cut the new class from the new DS and manually add it to existing DS and metadata and then delete the newly created DS, and build.

    Are you saying this feature is now built into RIA? if yes, please tell me how I can use it.

    Sorry for the new post, couldn’t add it to previous one!


  5. BradA says:

    >Brad, I see one important step that’s missing in two >sections of article.

    >When you added a new field (SuperPower) to the >SuperEmployee and updated the EDMX file or when >you added the contact file to your EDMX file, you >said "do a full build and everything should be >good", however a build does not add the new field >or file to the DomainService that already exist. This >is one very important step missing, because how do >you get DomainService to generate/add these new >entities?

    >I went back & forth and don’t see how a build adds >those in.

    Ben — Thanks for the comment.   I think i did handle those in the post, but maybe I was too smooth about it 😉

    The new field (SuperPower) does not need to be added to the DomainService in this case.. just updating the entity does the work.

    The new entity (Contact) does need to be added to the DomainService and I showed that…  You can optionally add it in the *.metadata.cs file for things such as validation…i showed that at the very end..  

  6. Delordson says:

    Great series!

    Would be very handy to see the use of the Combobox in datagrids, dataforms and child windows.

    Keep them coming!

  7. Rajiv Singh says:

    It Would be very helpful if u can include samples for combobox..Scenarios like data from different table loads in the combo box and its associated key get updated in a master table…

  8. Bo Soegaard says:

    I have a small problem with the TextBlock/AutoCompleteBox! After each key input the Textbox loses focus and the Autocomplete dropdown show for 3 sec. and then dropdown disapear, And the grid is filtered with the string in the textbox?.


  9. Sanjay says:

    Is there any samples for SL3/RIA/Childwindow/dataform/combo box combination?

  10. Thierry says:

    I notice the use of [Include] attribute, but imagine we have to filter contacts with a boolean field named ‘Active’ and we only want to retrieve Active contacts, is there a solution to make this in 1 query ?

  11. nisbus says:

    Although this sample includes a parent child relationship the save methods for these entities don’t update the relationships in the database.

    What I’m struggling with is how do I create a new child and hook it up to the parent?

    I’ve tried doing something like this in my code:

           private void OKButton_Click(object sender, RoutedEventArgs e)


               var parent = (Parents)(this.newContainerForm.FindNameInContent("ParentComboBox") as ComboBox).SelectedItem;

               NewChild.Parent = parent;


               this.DialogResult = true;


    Even if the service saves the child (which for some reason it doesn’t do any more), I’m always missing the Parent_Id from the database.

    Do the RIA Services support Cascading updates when using the [Include] attribute or is this only for single table services ?


  12. Sanjay says:

    Delordson thanks for the link. But add is not working correctly. I am still struggling to get it work. i have posted the issue in that link also.



  13. talent says:

    Hello Brad,

    I’ve a question. I’ve already joined 2 tables but I don’t know how to join 3 tables. I’ve Order 1-n OrderDetail and Order 1-n City. I want to select OrderDetail table and CityName from City table where OrderID = ‘###’. How Linq expression for this.

    Help me please. Thanks u very much.

  14. talent says:

    🙂 I solved my problem

    Instead of using syntax:

    include("Order").include("Order.City") I used:


    That’s my wrong.

  15. talent says:

    Hi Brad,

    Today I’ve a question.

    How do I can select subset of fields from entity in ADO.NET Data Service. I see almost examples here select all fields from entity.

    Thanks you!

  16. Steve says:

    I also can’t seem to get the commitEdit() to work…for the purpose of adding a record to the employee table in the "Walkthrough: Creating your first .NET RIA services Application".   Does anyone have a solution?

  17. Jon says:

    I am also not able to get the commitEdit(0 to work.  Any help?

  18. Eugen says:

    hi Brad

    nice article, however one issue, I have my DomainService derived from LinqToSqlDomainService and it doesn’t have Include method in linq query?

    Any idea?

  19. bts says:

    Hi Brad!

    I love your series, and love the concept of ria services even more.

    But, I think there is a bug in the sample code (since the first version) , because if you add a new product, it wouldn’t appear in the product grid as long as submitting the grid. How could it be corrected? – I have no Idea.

    Thank you in advance!

  20. bts says:

    Hello Brad!

    I didn’t get answer to my question, so I try expound it a little deeper.  I am not too experienced in silverlight and very new in net ria services. When I try own my own test appl upon your super employee appl,  there is three issues in connetion this:

    1) I have seen, there is no elaboration to refresh the employee datagrid after inserting a superemp (Nothing will be happen with the grid). But if you click the  submit button, the newly inserted records will appear in the grid. I have no idea how to enforce refreshing the grid without submitting the data to the server.

    2) How could be mark the updated entities in the datagrid (for example with an asterix) ? Itt would be very important to show in the tableview wich eelement was channged.

    3) In the details dataform of the sample, if you make any modification you can cancel it, but after leaving the element (in this case choosing an other employee) you cannnot cancel anymore in spite of that, the dataform marks that the record changed?!

    Thanks in advance

  21. Quinton says:

    Could you possible create some of the same examples using LinqToSQL instead of Entity framework? Some of my data models don’t compile with Entity but work perfectly with LinqToSQL

  22. Ra says:

    Brad, Thanks a lot for your blog series. It convinced me to use RIA Services which are pretty handy.

    I’m looking for a workaround for my RIA Services project, which has a Listbox with the Listitems as a user control defined as an ItemTemplate, like this:

    <ListBox x:Name="lstMain">   <ListBox.ItemTemplate>    


    <StackPanel Orientation="Horizontal">           <foo:ListItemDetail />      





    The Listbox is bound to a Domain Service in the code-behind. The List items are of type ListItemDetail, which has editable fields and an Update button. I’d like to call the Domain Service (the parent Lists’s Data Context) to SaveChanges() and update the item when the button is clicked, but there is no way to get to the (original) Domain Service that populated the list. Is there an elegant solution for this?

    I am trying to use the Listbox tag item to store the domain context, but I am unable to get to it from a ListItem. I get the parent StackPanel, but it’s parent is null.

    Thanks in advance

  23. John Woodford says:

    Brad, the series is indispensible when trying to work your way through all this stuff.

    I have done as you suggested above , added new columns to the table, updated the entity model and built the project but the does not update with the new fields.

    I do have multiple related entities in my model and have also produced a metadata.shared.cs. Does this cause a problem ?


  24. Mike Graham says:

    Excellent post…  you end the post by adding attributes to the generated metadata.cs class and doesn’t discuss how to update the metadata.cs class when the model changes.

    Here’s my update plan in the absence of clever tooling: Make two DomainServices MyDomainService, and MyDomainServiceOrig.  When I regenerate the model, I will replace MyDomainServiceOrig (including the metadata.cs).  I can then use source control to see what model changes occured between the previous and current metadata.cs.

    Then I’ll manually add the changes to MyDomainService.metadata.cs so as not to disturb the attributes I’ve manually added there.

  25. karthik says:

    Hi Brad,

    Can u see the above url posted by you,everthings workins fine for me,but i am not able to add new records and also delete.

    Even the demo application does not have the features.

    Please help me out brad i need to do it as it is urgent.. do repl to the post.

Skip to main content