Modifying and Deleting Entity Data (WCF Data Services/Silverlight)

Microsoft Silverlight will reach end of support after October 2021. Learn more.

In this task, you will extend the code from the previous task to enable you to update and delete existing Order_Details objects and then asynchronously send these changes back to the data service. The methods that handle the events that are raised by the controls call the UpdateObject and DeleteObject methods to set the state of the object in the DataServiceContext. The BeginSaveChanges and EndSaveChanges methods on the DataServiceContext are called asynchronously to save changes back to the data service.

To enable updating and deleting loaded objects

  1. Open the MainPage.xaml.cs source code file of the Silverlight project.

  2. In the public constructor method for the MainPage class, insert the following code that registers handlers for the Click events for the Delete Item and Save ChangesButton controls.

    ' Register handlers for the button Click events.
    AddHandler deleteDetail.Click, AddressOf deleteDetail_Click
    AddHandler saveChanges.Click, AddressOf saveChanges_Click
    
    // Register handlers for the button Click events.
    deleteDetail.Click += new RoutedEventHandler(deleteDetail_Click);
    saveChanges.Click += new RoutedEventHandler(saveChanges_Click);
    
  3. In the public constructor method for the MainPage class, insert the following code that registers a handler for the KeyDown event of the DataGrid, which is used to report an object as updated.

    ' Register a handler for the Key Down event that is raised when 
    ' a detail property is changed in the data grid.
    AddHandler detailsGrid.KeyDown, AddressOf detailsGrid_KeyDown
    
    // Register a handler for the Key Down event that is raised when 
    // a detail property is changed in the data grid.
    detailsGrid.KeyDown += new KeyEventHandler(detailsGrid_KeyDown);
    
  4. Add the following method to the MainPage class. This method is called when a key is pressed and the detailsGrid has the focus. By handling the KeyDown event, we assume that the user has made a change to the value of an order detail, and UpdateObject is called supplying the currently selected Order_Detail object.

    Private Sub detailsGrid_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)
        ' Update the current order in the context.
        svcContext.UpdateObject(detailsGrid.SelectedItem)
    End Sub
    
    private void detailsGrid_KeyDown(object sender, KeyEventArgs e)
    {
        // Update the current order in the context.
        svcContext.UpdateObject(detailsGrid.SelectedItem);
    }
    
  5. Add the following method to the MainPage class. This method is called when the Delete Item button is clicked. The handler for the Click event of the Delete Item button calls the DeleteObject method for the currently selected item and removes the item from the binding collection.

    Private Sub deleteDetail_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        Dim deletedItem = CType(detailsGrid.SelectedItem, Order_Detail)
    
        ' Delete the selected order.
        svcContext.DeleteObject(deletedItem)
    
        ' Remove the deleted order from the binding collection.
        If detailsGrid.SelectedIndex = 0 Then
            detailsGrid.SelectedIndex = 1
        Else
            detailsGrid.SelectedIndex = detailsGrid.SelectedIndex - 1
        End If
    
        detailsBindingCollection.Remove(deletedItem)
    End Sub
    
    private void deleteDetail_Click(object sender, RoutedEventArgs e)
    {
        Order_Detail deletedItem = (Order_Detail)detailsGrid.SelectedItem;
    
        // Delete the selected order.
        svcContext.DeleteObject(deletedItem);
    
        // Remove the deleted order from the binding collection.
        detailsGrid.SelectedIndex =
            detailsGrid.SelectedIndex == 0 ? 1 : detailsGrid.SelectedIndex - 1;
        detailsBindingCollection.Remove(deletedItem);
    }
    
  6. Add the following methods to the MainPage class. These methods are called when the Save Changes button is clicked. The handler for the Click event of the Save Changes button calls the BeginSaveChanges method to start a batched, asynchronous save changes operation. The OnChangesSaved method handles the result of this asynchronous operation by calling the EndSaveChanges method, parsing the returned OperationResponse objects, and printing out the response status codes.

    Private Sub saveChanges_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        ' Define the delegate to callback into the process
        Dim callback As AsyncCallback = AddressOf OnChangesSaved
    
        ' Start the saving changes operation. This needs to be a 
        ' batch operation in case we are added a new object with 
        ' a new relationship.
        svcContext.BeginSaveChanges(SaveChangesOptions.Batch, _
            callback, svcContext)
    End Sub
    Private Sub OnChangesSaved(ByVal result As IAsyncResult)
        ' Persist the result for the delegate.
        currentResult = result
    
        ' Use the Dispatcher to ensure that the 
        ' asynchronous call returns in the correct thread.
        Dispatcher.BeginInvoke(AddressOf ChangesSavedByDispatcher)
    End Sub
    Private Sub ChangesSavedByDispatcher()
        'Get the context from the callback.
        svcContext = CType(currentResult.AsyncState, NorthwindEntities)
    
        Try
            ' Complete the save changes operation and display the response.
            WriteOperationResponse(svcContext.EndSaveChanges(currentResult))
        Catch ex As DataServiceRequestException
            ' Display the error from the response.
            WriteOperationResponse(ex.Response)
        Catch ex As InvalidOperationException
            messageTextBlock.Text = ex.Message
        Finally
            ' Set the order in the grid.
            ordersGrid.SelectedItem = currentOrder
        End Try
    End Sub
    Private Sub WriteOperationResponse(ByVal response As DataServiceResponse)
        messageTextBlock.Text = String.Empty
        Dim i As Integer = 1
    
        If response.IsBatchResponse Then
            messageTextBlock.Text = String.Format("Batch operation response code: {0}" & vbCrLf, _
                response.BatchStatusCode)
        End If
        For Each change As ChangeOperationResponse In response
            messageTextBlock.Text = messageTextBlock.Text & _
                String.Format(vbTab & "Change {0} code: {1}" & vbCrLf, _
                i.ToString(), change.StatusCode.ToString())
            If change.Error IsNot Nothing Then
                messageTextBlock.Text = messageTextBlock.Text & _
                    String.Format(vbTab & "Change {0} error: {1}" & vbCrLf, _
                    i.ToString(), change.Error.Message)
            End If
            i = i + 1
        Next
    End Sub
    
    private void saveChanges_Click(object sender, RoutedEventArgs e)
    {
        // Start the saving changes operation. This needs to be a 
        // batch operation in case we are added a new object with 
        // a new relationship.
        svcContext.BeginSaveChanges(SaveChangesOptions.Batch, 
            OnChangesSaved, svcContext);
    }
    
    private void OnChangesSaved(IAsyncResult result)
    {
        // Use the Dispatcher to ensure that the 
        // asynchronous call returns in the correct thread.
        Dispatcher.BeginInvoke(() =>
            {
                svcContext = result.AsyncState as NorthwindEntities;
    
                try
                {
                    // Complete the save changes operation and display the response.
                    WriteOperationResponse(svcContext.EndSaveChanges(result));
                }
                catch (DataServiceRequestException ex)
                {
                    // Display the error from the response.
                    WriteOperationResponse(ex.Response);
                }
                catch (InvalidOperationException ex)
                {
                    messageTextBlock.Text = ex.Message;
                }
                finally
                {
                    // Set the order in the grid.
                    ordersGrid.SelectedItem = currentOrder;
                }
            }
        );
    }
    private void WriteOperationResponse(DataServiceResponse response)
    {
        messageTextBlock.Text = string.Empty;
        int i =1;
    
        if (response.IsBatchResponse)
        {
            messageTextBlock.Text = string.Format("Batch operation response code: {0}\n",
                response.BatchStatusCode);
        }
        foreach (ChangeOperationResponse change in response)
        {
            messageTextBlock.Text += 
                string.Format("\tChange {0} code: {1}\n", 
                i.ToString(), change.StatusCode.ToString());
            if (change.Error != null)
            {
                messageTextBlock.Text +=
                string.Format("\tChange {0} error: {1}\n", 
                    i.ToString(), change.Error.Message);
            }
            i++;
        }
    }
    

To build and run the application

  1. From the Debug menu, select Start Debugging or Start Without Debugging.

    This builds and starts the application.

  2. When the page loads, enter a value in the Customer ID text box (a valid value of ALFKI is provided), and then click Get Orders.

    This displays the orders that belong to that customer.

  3. Change the quantity of an item in the order or click the Delete Item button.

    This marks the item in the context to be updated or deleted when changes are saved.

  4. Click the Save Changes button.

    This saves changes to the data service and displays the result codes from the batch operation.

Next Steps

You have successfully enhanced the client application for Silverlight by adding the ability to update and delete Order_Details objects and save changes to the data service. Finally, you will create a new Order_Details object that has the required links to the related Orders and Products objects:

Creating New Entities with Relationships

See Also

Other Resources