Deborah's Developer MindScape






         Tips and Techniques for Web and .NET developers.

July 19, 2010

SL/RIA/POCO: Update Data

Filed under: ASP.NET RIA Services,C#,Silverlight,VB.NET @ 2:55 pm

The prior post here detailed how to build a simple Silverlight application that used WCF RIA Services to communicate with your server-side business layer to retrieve data and display it in a Silverlight DataGrid. This post adds to the prior post, providing an update feature.

In keeping with the general theme of the prior post, this post is going to provide the simplest technique for performing an update in a Silverlight application using your own Plain Old CLR Objects (POCOs) that reside on the server.

So first, the prerequisites:

1) Follow the steps in the prior post here.

2) Build the Data Access Layer.

The prior post "mocked" the data access by returning a simple list from the business layer retrieve method. To try out the save, this won’t suffice. The code needs real data access.

Use the information in the post defined here to build your data access layer.

3) Change your Customer class to call the Data Access layer.

In the prior post, the Customer class Retrieve method returned a hard-coded set of customers. This method needs to change to use the Data Access layer. In addition, the code needs a Save method to save the customer data.

In C#:

public List<Customer> Retrieve()
{
    List<Customer> custList = new List<Customer>();

    DataTable dt = Dac.ExecuteDataTable("CustomerRetrieve");

    foreach (DataRow dr in dt.Rows)
    {
        Customer cust = new Customer
        {
            CustomerId = (int)dr["CustomerId"],
            LastName = dr["LastName"].ToString(),
            FirstName = dr["FirstName"].ToString(),
            EmailAddress = dr["EmailAddress"].ToString()
        };
        custList.Add(cust);
    }

    return custList;
}

public bool Save()
{
    bool success = true;

    // Call the save
    int returnId = Dac.ExecuteNonQuery("CustomerUpdate",
                    new SqlParameter("CustomerId", CustomerId),
                    new SqlParameter("LastName", LastName),
                    new SqlParameter("FirstName", FirstName),
                    new SqlParameter("EmailAddress", EmailAddress));

    if (returnId != 0)
        this.CustomerId = returnId;

    return success;
}

In VB:

Public Function Retrieve() As List(Of Customer)
    Dim custList As New List(Of Customer)

    Dim dt As DataTable = Dac.ExecuteDataTable("CustomerRetrieve")

    For Each dr As DataRow In dt.Rows
        Dim cust As New Customer With {
           .CustomerId = CType(dr("CustomerId"), Integer),
           .LastName = dr("LastName").ToString(),
           .FirstName = dr("FirstName").ToString(),
           .EmailAddress = dr("EmailAddress").ToString()}
        custList.Add(cust)
    Next
    Return custList
End Function

Public Function Save() As Boolean
    Dim success As Boolean = True

    ‘ Call the save
    Dim returnId As Integer = Dac.ExecuteNonQuery("CustomerUpdate",
                    New SqlParameter("CustomerId", Me.CustomerId),
                    New SqlParameter("LastName", Me.LastName),
                    New SqlParameter("FirstName", Me.FirstName),
                    New SqlParameter("EmailAddress", Me.EmailAddress))

    If returnId <> 0 Then
        Me.CustomerId = returnId
    End If

    Return success
End Function

NOTE: Normally I build a Customer class (singular) with the properties and methods that mange a single customer and a Customers class (plural) that works with a list of those customers. The functionality for both were added to one class to keep this example as simple as possible.

Once the prerequisites are in place, we can get started.

STEP 1: Add an Update method to the Domain Service class

Open the Domain Service class and add an update method.

In C#:

public void UpdateCustomer(Customer updatedCustomer)
{

}

In VB:

Public Sub UpdateCustomer(ByVal updatedCustomer As Customer)

End Sub

A few notes about this UpdateCustomer method:

  • It must be a method.
  • Must have no return value.
  • Must pass the entity as a parameter.
  • Must either:
    • Start with "Update", "Change" or "Modify
    • Or have an Update attribute

WCF RIA Services recognizes the method as an update method because of its name or Update attribute. It recognizes it as an update of a Customer by its parameter. This method is required for an update operation to be valid in the Silverlight application.

This method does not require any code, unless you want to perform some additional operations on an update. However, the method still needs to exist for the DomainDataSource on the page to accept updates.

This method is called when the code calls SubmitChanges, as shown later in this post.

STEP 2: Override the PersistChangeSet method

The PersistChangeSet method is called when the code calls SubmitChanges, after the code calls the Update method. Use this method to call the Save method on your business objects.

In C#:

protected override bool PersistChangeSet()
{
    Customer changedCustomer;
    bool success = true;

    foreach (var item in ChangeSet.ChangeSetEntries)
    {
        if (item.Entity.GetType() == typeof(Customer))
        {
            changedCustomer = (Customer)item.Entity;
            success = changedCustomer.Save();
            if (!success)
                break;
        }
    }
    return success;
}

In VB:

Protected Overrides Function PersistChangeSet() As Boolean
    Dim changedCustomer As Customer
    Dim success As Boolean = True

    For Each item In ChangeSet.ChangeSetEntries
        If item.Entity.GetType() = GetType(Customer) Then
            changedCustomer = DirectCast(item.Entity, Customer)
            success = changedCustomer.Save()
            If Not success Then
                Exit For
            End If
        End If
    Next
    Return success
End Function

WCF RIA Services keeps track of any changes to the entities in the application (Customer in this example). You can access the set of changes using the ChangeSet property.

The Customer class in this example has a Save method that saves one specific customer. So the above code loops through the customers in the ChangeSet and calls the Save method on the customer.

This would be more efficient if you had a Customers class (as mentioned in the Note earlier in this post). Your Customers class could have a save method against a list of customers. You could then call Customers.Save to save all of your customer change instead of calling Save on each individual customer.

STEP 3: Build the UI

Again, keeping with the goal of staying as simple as possible, the UI in this example is a simple set of properties.

1) Open the designer for MainPage.xaml by double-clicking on the file.

2) Open the Data Sources window (Data | Show Data Sources).

Visual Studio automatically added the defined domain context class to your data sources. Change the default UI from a data grid to a details view:

image

3) Drag and drop the Customer data source onto the designer to the right of the grid (created in the prior post) and Visual Studio creates the user interface for you:

image

4) Add the Save button as shown above.

In the code behind for the Save button, add code as follows.

In C#:

private void SaveButton_Click(object sender, RoutedEventArgs e)
{
    if (customerDomainDataSource.HasChanges)
        customerDomainDataSource.SubmitChanges();
}

In VB:

Private Sub SaveButton_Click(ByVal sender As System.Object, 
  ByVal e As System.Windows.RoutedEventArgs) Handles SaveButton.Click
    If CustomerDomainDataSource.HasChanges Then
        CustomerDomainDataSource.SubmitChanges()
    End If
End Sub

This code checks for changes and if the DomainDataSource on the page is changed, it calls SubmitChanges. SubmitChanges first calls the UpdateCustomer method and then the PersistChangeSet method, which in turn calls the Save method of the Customer business object.

STEP 4: Run

If you run the application, you should get this:

image

This works because when you drag and drop the data source onto the page, Visual Studio defines the labels and textboxes and binds the textboxes to the DomainDataSource that was added in the prior post. The DomainDataSource takes care of managing the updates.

For a more complete example, download the extended source from here.

If you want to learn more about using Silverlight and RIA Services, come and see my talk at VSLive in Redmond Washington August 4, 2010. See this post for more information.

Use these techniques as a starting point when performing update operations using your server-side business layer from a Silverlight application.

Enjoy!

1 Comment

  1.   Rohit — March 22, 2011 @ 1:47 am    Reply

    How to perform form validation for own business objects

RSS feed for comments on this post. TrackBack URI

Leave a comment

© 2019 Deborah's Developer MindScape   Provided by WPMU DEV -The WordPress Experts   Hosted by Microsoft MVPs