Creating New Entities with Relationships (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 create new Order_Details objects along with the required links to the related Orders and Products objects. The method that handles the Click event that is raised by the Insert Item button calls the AddToOrder_Details method to add a new item to the DataServiceContext. It also calls the AddLink method to create the links to the related Orders and Products objects. The new objects and relationship links are sent to the data service in a single batch when BeginSaveChanges is called.

To insert a new Order_Details object with relationships

  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 event for the Insert ItemButton.

    AddHandler addDetail.Click, AddressOf addDetail_Click
    
    addDetail.Click += new RoutedEventHandler(addDetail_Click);
    
  3. Add the following methods to the MainPage class. These methods are called when the Insert Items button is clicked. The handler for the Click event of the Insert Item button first executes a data service query to get the Products object with the specified ID, which is required, along with the currently selected Orders object, to create the links to the new Order_Details object. When the asynchronous query returns with a Products object, the static CreateOrder_Details method is called on Order_Details to create a new instance that has the ID values from the related Orders and Products objects. This new object is then added to the binding collection, and the AddToOrder_Details method on NorthwindEntities is called to add the new object to the DataServiceContext. The AddLink method is also called to create the relationships between the new Order_Details object and the related objects. For consistency on the client, the navigation properties on the new Order_Details object are also sent, although this is not required.

    Private Sub addDetail_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        ' Define the delegate to callback into the process
        Dim callback As AsyncCallback = AddressOf OnProductQueryCompleted
    
        ' Define a URI that returns the product with the specified ID.
        Dim productUri = New Uri(svcContext.BaseUri.AbsoluteUri & _
            "/Products(" & Me.productId.Text & ")")
    
        ' Begin a query operation retrieve the Product object 
        ' that is required to add a link to the new Order_Detail.
        svcContext.BeginExecute(Of Product)(productUri, _
            callback, Nothing)
    End Sub
    
    Private Sub OnProductQueryCompleted(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 ProductQueryCompletedByDispatcher)
    End Sub
    Private Sub ProductQueryCompletedByDispatcher()
        ' Get the Product returned by the completed query.
        Dim queryResult As IEnumerable(Of Product) = _
        svcContext.EndExecute(Of Product)(currentResult)
    
        Dim returnedProduct = queryResult.First()
    
        ' Create a new Order_Details object with the supplied FK values.
        Dim newItem = Order_Detail.CreateOrder_Detail(currentOrder.OrderID, _
            returnedProduct.ProductID, 0, 0, 0)
    
        detailsBindingCollection.Add(newItem)
    
        ' Add the new item to the context.
        svcContext.AddToOrder_Details(newItem)
    
        ' Add the relationship between the order and the new item.
        currentOrder.Order_Details.Add(newItem)
        svcContext.AddLink(currentOrder, "Order_Details", newItem)
    
        ' Set the reference to the order and product from the item.
        newItem.Order = currentOrder
    
        ' Add the relationship between the product and the new item.
        returnedProduct.Order_Details.Add(newItem)
        svcContext.AddLink(returnedProduct, "Order_Details", newItem)
    
        ' Set the reference to the product from the item.
        newItem.Product = returnedProduct
    End Sub
    
    private void addDetail_Click(object sender, RoutedEventArgs e)
    {
        // Define a URI that returns the product with the specified ID.
        Uri productUri = new Uri(svcContext.BaseUri.AbsoluteUri
            + "/Products(" + this.productId.Text + ")");
    
        // Begin a query operation retrieve the Product object 
        // that is required to add a link to the new Order_Detail.
        svcContext.BeginExecute<Product>(productUri,
            OnProductQueryCompleted, null);
    }
    
    private void OnProductQueryCompleted(IAsyncResult result)
    {
        // Use the Dispatcher to ensure that the 
        // asynchronous call returns in the correct thread.
        Dispatcher.BeginInvoke(() =>
            {
                // Get the Product returned by the completed query.
                IEnumerable<Product> queryResult =
                    svcContext.EndExecute<Product>(result);
                Product returnedProduct = queryResult.First();
    
                // Create a new Order_Details object with the supplied FK values.
                Order_Detail newItem = Order_Detail.CreateOrder_Detail(currentOrder.OrderID,
                    returnedProduct.ProductID, 0, 0, 0);
    
                detailsBindingCollection.Add(newItem);
    
                // Add the new item to the context.
                svcContext.AddToOrder_Details(newItem);
    
                // Add the relationship between the order and the new item.
                currentOrder.Order_Details.Add(newItem);
                svcContext.AddLink(currentOrder, "Order_Details", newItem);
    
                // Set the reference to the order and product from the item.
                newItem.Order = currentOrder;
    
                // Add the relationship between the product and the new item.
                returnedProduct.Order_Details.Add(newItem);
                svcContext.AddLink(returnedProduct, "Order_Details", newItem);
    
                // Set the reference to the product from the item.
                newItem.Product = returnedProduct;
            }
        );
    }
    

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. Click the Add Item button.

    This adds a new item, related to the specific product and selected order, to the items grid and also adds the new items to the context with the related links.

  4. Click the Save Changes button.

    This saves changes and creates the new entity in the data service in a single batch and displays the result codes from the batch operation.

Next Steps

You have successfully created the client application for Silverlight that accesses WCF Data Services. For more information, see Working with .NET Framework Client Libraries (WCF Data Services).

See Also

Other Resources