How it works: Track Changes using the Change Tracking Proxies mechanism

Description Article
Table of Contents
Summary

If preferred, Entity Framework is be able to create dynamic proxies capable of tracking changes and communicate them to the change tracker at runtime.

Description

Enabling and working with Dynamic proxies

To enable the use of dynamic proxies for automatic track changes are described on this article.

The change tracking proxy will override any collection navigation properties and use its own collection type (EntityCollection<TEntity>). This collection type will track any changes to the collection and report them to the change tracker. Any attempt to assign another type to the property (e.g. List<T>)  the proxy will throw an exception.

When Entity Framework creates the dynamic proxy for change tracking, it will implement the IEntityWithChangeTracker interface.

Operations
Verify if an object s dynamic proxy created for change tracking
How to do it
using (var context = new BreakAwayContext())
  {
    var destination = context.Destinations.First();

    var isProxy = destination is IEntityWithChangeTracker;

    Console.WriteLine("Destination is a proxy: {0}", isProxy);
  }
Create a dynamic proxy for the new entity class instances

Entity Framework will automatically create proxies for the results of any executed queries.

However, if the constructor of the original POCO class is used to create new entitiy objects, these will not be proxies.

In order to get proxies the DbSet.Create method must be used to get new instances of an entity. This rule is the same as when working with POCOs with ObjectContext and ObjectSet.

How to do it
using (var context = new BreakAwayContext())
  {
    var nonProxy = new Destination();
    nonProxy.Name = "Non-proxy Destination";
    nonProxy.Lodgings = new List<Lodging>();

    var proxy = context.Destinations.Create();
    proxy.Name = "Proxy Destination";

    context.Destinations.Add(proxy);
    context.Destinations.Add(nonProxy);

    var davesDump = (from l in context.Lodgings
                     where l.Name == "Dave's Dump"
                     select l).Single();

    context.Entry(davesDump)
      .Reference(l => l.Destination)
      .Load();

    Console.WriteLine(
      "Before changes: {0}",
      davesDump.Destination.Name);

    nonProxy.Lodgings.Add(davesDump);

    Console.WriteLine(
      "Added to non-proxy destination: {0}",
      davesDump.Destination.Name);

    proxy.Lodgings.Add(davesDump);

    Console.WriteLine(
      "Added to proxy destination: {0}",
      davesDump.Destination.Name);
  }
Create proxy instances for drerived types

There is also a generic overload of DbSet.Create method that is used to create instances of derived classes in a set.

To get a new proxy instance of a derived typeResort, the generic overload must be used.

How to do it

To get a new proxy instance of Resort class, that is derived from the Lodging class:

var newResort = context.Lodgings.Create<Resort>();
Fetching entites without change tracking

In some scenarios, like when the data is only for display in a read-only screen, the change tracking is usefulless because the data will never be updated.

If this is the case, Entity Framework includes an DbSet.AsNoTracking method that can be used to execute a no-tracking query.

How to do it
using (var context = new BreakAwayContext())
  {
    foreach (var destination in context.Destinations.AsNoTracking())
    {
      Console.WriteLine(destination.Name);
    }
  }