Updating the Data Service (ADO.NET Data Services)

Note

This topic describes new functionality in ADO.NET Data Services that is available as an update to the .NET Framework version 3.5 Service Pack 1. You can download and install the update from the Microsoft Download Center.

When you use the ADO.NET Data Services client library to access data in a data service, the library translates the response message into instances of client data service classes. These data service classes are tracked by the DataServiceContext to which the DataServiceQuery belongs. The DataServiceContext tracks added and deleted entities and also changes that you made to property values or to relationships between entity instances and sends those entities back to the data service as REST-based operations when you call the SaveChanges() method. You can also save changes asynchronously by using the BeginSaveChanges(AsyncCallback, Object) and EndSaveChanges(IAsyncResult) methods. For more information, see Asynchronous Operations (ADO.NET Data Services).

Adding, Modifying, and Changing Entities

When you use the Add Service Reference dialog in Visual Studio to add a data service reference, the resulting client data service classes each have a static Create method that takes one parameter for each non-nullable entity property. You can use this method to create instances of entity type classes, as in the following example:

' Create the new product.
Dim newProduct = Products.CreateProducts(0, "White Tea - loose", False)
// Create the new product.
Products newProduct =
    Products.CreateProducts(0, "White Tea - loose", false);

To add an entity instance, call the appropriate AddTo method on the DataServiceContext class generated by the Add Service Reference dialog, as in the following example:

' Add the new product to the Products entity set.
context.AddToProducts(newProduct)
// Add the new product to the Products entity set.
context.AddToProducts(newProduct);

This adds the object to the context and into the correct entity set. You can also call AddObject(String, Object), but you must instead supply the entity set name. If the added entity has one or more relationships to other entities, you can either use the AddRelatedObject(Object, String, Object) method or use one of the previous methods and also explicitly define those links. These operations are discussed later in this topic.

To modify an existing entity instance, first query for that entity, make the desired changes to its properties, and then call the UpdateObject(Object) method on the DataServiceContext to indicate to the client library that it needs to send an update for that object, as shown in the following example:

' Mark the customer as updated.
context.UpdateObject(customerToChange)
// Mark the customer as updated.
context.UpdateObject(customerToChange);

To delete an entity instance, call the DeleteObject(Object) method on the DataServiceContext, as shown in the following example:

' Mark the product for deletion.    
context.DeleteObject(deletedProduct)
// Mark the product for deletion.    
context.DeleteObject(deletedProduct);

For more information, see How to: Add, Modify, and Delete Entities (ADO.NET Data Services).

Saving Changes

Changes are tracked in the DataServiceContext instance but not sent to the server immediately. After you are finished with the required changes for a specified activity, call SaveChanges() to submit all the changes to the data service. A DataServiceResponse object is returned after the SaveChanges() operation is complete. The DataServiceResponse object includes a sequence of ChangesetResponse objects that, in turn, contain a sequence of EntityDescriptor or LinkDescriptor instances that represent the changes persisted or attempted. When an entity is created or modified in the data service, the EntityDescriptor includes a reference to the updated entity, including any server-generated property values, such as the generated ProductID value in the previous example. The client library automatically updates the .NET Framework object to have these new values.

For successful insert and update operations, the state property of the EntityDescriptor or LinkDescriptor object associated with the operation is set to Unchanged() and the new values are merged by using OverwriteChanges().

When an insert, update, or delete operation fails in the data service, the entity state remains the same as it was before SaveChanges() was called, and the Error() property of the LinkDescriptor or EntityDescriptor is set to an DataServiceRequestException that contains information about the error.

Attaching Entities

The client library enables you to save updates that you made to an entity without first executing a query to load the entity into the DataServiceContext. Use the AttachTo(String, Object) method to attach an existing object to a specific entity set in the DataServiceContext. You can then modify the object and save the changes to the data service. In the following example, a customer object that has been changed is attached to the context and then UpdateObject(Object) is called to mark the attached object as Modified() before SaveChanges(SaveChangesOptions) is called:

' Attach the existing customer to the context and mark it as updated.
context.AttachTo("Customers", customer)
context.UpdateObject(customer)

' Send updates to the data service.
context.SaveChanges()
// Attach the existing customer to the context and mark it as updated.
context.AttachTo("Customers", customer);
context.UpdateObject(customer);

// Send updates to the data service.
context.SaveChanges();

The following considerations apply when attaching objects:

  • An object is attached in the Unchanged() state.

  • When an object is attached, objects that are related to the attached object are not also attached.

  • An object cannot be attached if the entity is already being tracked by the context.

  • The AttachTo(String, Object, String) method overload that takes an etag parameter is used when you attach an entity object that was received along with an eTag value. This eTag is then used to check for concurrency when changes to the attached object are saved.

For more information, see How to: Attach an Existing Entity to the DataServiceContext (ADO.NET Data Services).

When you add a new entity by using either the AddObject(String, Object) method or the appropriate AddTo method of the DataServiceContext class that the Add Service Reference dialog generates, any relationships between the new entity and related entities are not automatically defined.

You can create and change relationships between entity instances and have the client library reflect those changes in the data service. Relationships between entities are defined as associations in the model, and the DataServiceContext tracks each relationship as a link object in the context. ADO.NET Data Services provides the following methods on the DataServiceContext class to create, modify, and delete these links:

Method

Description

AddRelatedObject(Object, String, Object)

Creates a new bi-directional link between two related entity objects. Calling this method is equivalent to calling AddLink followed by SetLink to define both directions of the relationship. Call this method for any type of relationship.

AddLink(Object, String, Object)

Creates a new link between two related entity objects. Call this method when you add the object to a collection of objects at the many end of a one-to-many or many-to-many relationship, such as when you add a new order to customer.

SetLink(Object, String, Object)

Creates a new link between two related entity objects. Call this method when you add the object as a reference at the zero-or-one end of a one-to-one or many-to-one relationship, such as when you assign an order to a customer.

DeleteLink(Object, String, Object)

Marks a link that the context is tracking for deletion when the SaveChanges() method is called. Use this method when you delete a related object or change a relationship by first deleting the link to an existing object and then adding a link to the new related object.

AttachLink(Object, String, Object)

Notifies the context of an existing link between two entity objects. The context assumes that this relationship already exists in the data service and does not try to create the link when you call the SaveChanges() method. Use this method when you attach objects to a context and need to also attach the link between the two. If you are defining a new relationship, you should instead use AddLink(Object, String, Object)/SetLink(Object, String, Object).

DetachLink(Object, String, Object)

Stops tracking the specified link in the context.

Note

Associations usually represent bi-directional relationships between entities. For example, the association between Customers and Orders entities represents both a relationship between a customer and one or more orders and also a relationship between an order and the customer to which it belongs. Because the relationships tend to be bi-directional, we recommend that you call the AddRelatedObject(Object, String, Object) method to define both directions of the relationship at the same time.

The following example shows how to use the AddRelatedObject(Object, String, Object) method to add a new Order_Detail that is related to an existing Orders entity. Because the new Order_Details object is now tracked by the DataServiceContext, the relationship of the added Order_Details object to the existing Products entity is defined by calling the AddLink(Object, String, Object) and SetLink(Object, String, Object) methods:

' Add the new item with a link to the related order.
context.AddRelatedObject(order, "Order_Details", newItem)
context.SetLink(newItem, "Orders", order)

' Since the item is now tracked by the context,
' set just the link to the related product.
context.AddLink(selectedProduct, "Order_Details", newItem)
context.SetLink(newItem, "Products", selectedProduct)
// Add the new item with a link to the related order.
context.AddRelatedObject(order, "Order_Details", newItem);
context.SetLink(newItem, "Orders", order);

// Since the item is now tracked by the context,
// set just the link to the related product.
context.AddLink(selectedProduct, "Order_Details", newItem);
context.SetLink(newItem, "Products", selectedProduct);

While the AddLink(Object, String, Object) and SetLink(Object, String, Object) methods define links that must be created in the data service, to have these links reflected in the objects that are in the context, you must also set the navigation properties on the objects themselves. In the previous example, you should set the navigation properties as follows:

' Add the new order detail to the collection, and
' set the reference to the product.
order.Order_Details.Add(newItem)
newItem.Orders = order
newItem.Products = selectedProduct
// Add the new order detail to the collection, and
// set the reference to the product.
order.Order_Details.Add(newItem);
newItem.Orders = order;
newItem.Products = selectedProduct;

For more information, see How to: Define Entity Relationships (ADO.NET Data Services).

See Also

Other Resources

Using a Data Service in a .NET Framework Application (ADO.NET Data Services)

Querying the Data Service (ADO.NET Data Services)

Asynchronous Operations (ADO.NET Data Services)

Batching Operations (ADO.NET Data Services)

Making Changes to Data (ADO.NET Data Services)