Working with Self-Tracking Entities

In an Entity Framework application, an object context is responsible for tracking changes in the entities in an object graph. However, in N-tier scenarios, the object context might not be available on the tier that modifies the entities. Starting with the .NET Framework version 4, self-tracking entities can help you track changes in any tier.

Note

Use self-tracking entities only if the object context is not available on a tier where the changes to the object graph are made. If the object context is available, use EntityObject derived types, or "plain-old" CLR objects (POCO) types, or POCO proxy types. For more information, see Working with Objects.

Starting with Microsoft Visual Studio 2010, the ADO.NET Self-Tracking Entity Generator template generates self-tracking entities. This template item generates two .tt (text template) files: <model name>.tt and <model name>.Context.tt. The <model name>.tt file generates the entity types and a helper class that contains the change-tracking logic that is used by self-tracking entities and the extension methods that allow setting state on self-tracking entities. The <model name>.Context.tt file generates a typed ObjectContext and an extension class that contains ApplyChanges methods for the ObjectContext and ObjectSet classes. These methods examine the change-tracking information that is contained in the graph of self-tracking entities to infer the set of operations that must be performed to save the changes in the database. For more information, see ADO.NET Self-Tracking Entity Generator Template.

Ff407090.Important(en-us,VS.100).gif Note:
A service should not trust requests to retrieve or update data from a non-trusted client or through a non-trusted channel. A client must be authenticated: a secure channel or message envelope should be used. Clients' requests to update or retrieve data must be validated to ensure they conform to expected and legitimate changes for the given scenario.

Ff407090.Important(en-us,VS.100).gif Note:
Avoid using sensitive information as entity keys (for example, social security numbers). This mitigates the possibility of inadvertently serializing sensitive information in the self-tracking entity graphs to a client that is not fully trusted. With independent associations, the original key of an entity that is related to the one that is being serialized might be sent to the client as well.

Self-Tracking Entity Extension Methods

The following extension methods can be applied to a self-tracking entity. If you want to perform these operations on a set of entities instead of just one, see Working with Sets of Self-Tracking Entities for more information.

StartTracking Method

The StartTracking method instructs the change tracker on the entity to start recording any changes applied to the entity. This includes changes to scalar properties, collections, and references to other entities. The self-tracking entities start tracking automatically when they are deserialized into the client through the Windows Communication Foundation (WCF). The tracking is also turned on for newly created entities in the following scenarios:

  • A relationship is created between the new entity and an entity that is already tracking changes.

  • The MarkAs[State] or AcceptChanges method is called on an entity.

StopTracking Method

The StopTracking method stops recording changes.

MarkAs Methods

All the MarkAs methods turn tracking on. These extension methods facilitate changing the state of an entity explicitly to Added, Modified, Deleted, and Unchanged.

The MarkAs[State] methods return the same entity they are applied to, with the modified state. The following example modifies the state of the entity to Unchanged:

department.Course = new Course { CourseID = courseID }.MarkAsUnchanged();

The MarkAsAdded method changes the state of the entity to Added. New self-tracking entities are created in the Added state with change tracking not enabled.

The MarkAsDeleted method changes the state of the entity to Deleted. This method also clears the navigation properties on the entity that is being marked for deletion. The navigation property is set to null if it is pointing to a reference object. The Clear method is called if the navigation property represents a collection. When MarkAsDeleted is called on an object that is part of a collection, the object is removed from the collection. To mark each object in a collection as deleted, mark the objects in a copy of the collection. To get the copy of the collection, call the ToArray() or ToList() method on the collection, as in the following example:

List<Course> courses = department.Courses.ToList();

foreach (var c in courses)

{

// Mark each course in the department as Deleted.

c.MarkAsDeleted();

}

The MarkAsModified method changes the state of the entity to Modified. Also, modifying the value of a property on an entity that has change tracking enabled sets the state to Modified.

The MarkAsUnchanged method changes the state of the entity to Unchanged. Also, AcceptChanges clears the change-tracking information for an entity and moves its state to Unchanged.

AcceptChanges

The AcceptChanges method clears the change-tracking information for an entity and changes its state to Unchanged. If you want to reset the state of a relationship, call AcceptChanges on both entities that participate in the relationship.

ObjectContext Extension Methods

The ApplyChanges method examines the change-tracking information that is contained in the graph of self-tracking entities and infers the set of operations that must be performed to reflect the changes in the database. There are two ApplyChanges methods, one for the ObjectContext and the other for the ObjectSet.

Note

To avoid propagating exception messages that contain sensitive data to the client tier, calls to ApplyChanges and SaveChanges on the server tier should be wrapped in exception-handling code.

Considerations When Working with Self-Tracking Entities

Consider the following when working with self-tracking entities:

  • Make sure that your client project has a reference to the assembly containing the entity types. If you add only the service reference to the client project, the client project will use the WCF proxy types and not the actual self-tracking entity types. This means that you will not get the automated notification features that manage the tracking of the entities on the client. If you intentionally do not want to include the entity types, you will have to manually set change-tracking information on the client for the changes to be sent back to the service.

  • Calls to the service operation should be stateless and create a new instance of object context. We also recommend that you create object context in a using block.

  • When you send the graph that was modified on the client to the service and then intend to continue working with the same graph on the client, you have to manually iterate through the graph and call the AcceptChanges method on each object to reset the change tracker. If objects in your graph contain properties with database-generated values (for example, identity or concurrency values), the Entity Framework will replace values of these properties with the database-generated values after the SaveChanges method is called. You can implement your service operation to return saved objects or a list of generated property values for the objects back to the client. The client would then need to replace the object instances or object property values with the objects or property values returned from the service operation.

  • Merging graphs from multiple service requests may introduce objects with duplicate key values in the resulting graph. The Entity Framework does not remove the objects with duplicate keys when you call the ApplyChanges method but instead throws an exception. To avoid having graphs with duplicate key values follow one of the patterns described in the following blog: Self-Tracking Entities: ApplyChanges and duplicate entities.

  • When you change the relationship between objects by setting the foreign key property, the reference navigation property is set to null and not synchronized to the appropriate principal entity on the client. After the graph is attached to the object context (for example, after you call the ApplyChanges method), the foreign key properties and navigation properties are synchronized.

    Not having a reference navigation property synchronized with the appropriate principal object could be an issue if you have specified cascade delete on the foreign key relationship. If you delete the principal, the delete will not be propagated to the dependent objects. If you have cascade deletes specified, use navigation properties to change relationships instead of setting the foreign key property.

  • Self-tracking entities are not enabled to perform lazy loading.

  • Binary serialization and serialization to ASP.NET state management objects is not supported by code generated from the ADO.NET Self-Tracking Entity Generator template. However, you can customize the template to add the binary serialization support. For more information, see Using Binary Serialization and ViewState with Self-Tracking Entities.

See Also

Tasks

Walkthrough: Serialize Self-Tracking Entities

Other Resources

Working with Sets of Self-Tracking Entities
Self-Tracking Entities in Silverlight
Using Binary Serialization and ViewState with Self-Tracking Entities