Sunday, March 18, 2012

Associated Metadata (Buddy) classes in C#

Partial classes allow us to define a class in different parts. At compile time, all these pieces are joined together and a type is generated. Now if we need to add something else to the class definition then we add another part and it is automatically added to type definition. Partial classes allow us to add new members to the same types. It does not directly allow us to be adding further description of already existing members.


Consider our example of WCF Service. It is exposing a list of students. Student type is provided to the client as a DataContract. It has two properties, FirstName and LastName. Both are of string type and decorated with DataMember attribute.
namespace Institute.Data
{
    using System.Runtime.Serialization;

    [DataContract]
    public partial class Student
    {
        [DataMember]
        public string FirstName { get; set; }

        [DataMember]
        public string LastName { get; set; }
    }
}
This is the same service as we defined in a previous post. You can find the definition of service here:

http://www.shujaat.net/2012/03/visual-studio-hosting-wcf-services.html

What if we want to allow the client of this service to be able to provide additional members. That is why we are providing it as a partial class. We might want to further decorate the FirstName and LastName properties with additional attributes. We can then do data validation based on these Data Annotation attributes. This can be done with another feature of .net framework, Associated Metadata classes. Developers also refer to it as Buddy Classes.

Let's add a service reference of InstituteDataService to our console application as follows:


We add a new class to the client. Let's call it StudentMetadata. Here we are just defining additional data annotation attributes to the same property names as the original partial class that we want additional attributes to be added to.
public sealed class StudentMetadata
{
    [Required]
    public string FirstName { get; set; }

    [StringLength(10)]
    public string LastName { get; set; }
}
In order to add these attributes, we need to add System.ComponentModel.DataAnnotations assembly reference. Now we need to map this buddy class [StudenMetadata] to the Student class. We need to add MetadataTypeAttribute to the Student class definition and specifying StudentMetadata as the buddy class as below:

[MetadataType(typeof(StudentMetadata))]
public partial class Student
{
}
We also need to add the mapping to the Type Descriptor definitions. This code can be executed at the startup of the client code.
TypeDescriptor.AddProvider(
        new AssociatedMetadataTypeTypeDescriptionProvider(
            typeof(Student)
            ), typeof(Student));
Now we just need to see how the description of the properties is affected after this.
foreach (PropertyDescriptor descriptor in
            TypeDescriptor.GetProperties(typeof(Student)))
{
    Console.WriteLine("*******************************");
    Console.WriteLine(string.Format("Property Name: {0}", descriptor.Name));
    foreach (Attribute attribute in descriptor.Attributes)
    {
        Console.WriteLine(string.Format("Attribute Name: {0}", attribute));
    }
}
The above code iterates through the property descriptors of all the properties of Student type. It then writes all the attributes to the console. This can result in the following output:


Please remember that if we access the information of PropertyInfo for the Student type, it would still return the same information. This is because this is not part of type definition but separate description of type is added. Let's add the following code:
PropertyInfo[] properties = typeof(Student).GetProperties();
foreach (var propertyInfo in properties)
{
    Console.WriteLine("*******************************");
    Console.WriteLine("Propery Name: {0}", propertyInfo.Name);
    foreach (Attribute attrib in propertyInfo.GetCustomAttributes(false))
    {
        Console.WriteLine("Attribute: {0}", attrib);
    }
}
This would result in the following output:


Please note that it has just considered DataMemberAttribute which is the definition of type from service reference. Framework developers can use the type description for generating proxies as a decoration of these types based on these additional type description attributes.

Download Code:

JetBrain's dotPeek for Decompiling .net assemblies

Since RedGate's .net reflector is a commercial tool now (which is not free), there has been a need for a free tool for decompiling .net assembly. Well, JetBrain has impressed yet again with its own product for disassembling. Although not officially released yet, the current version of the build was pushed on December 29, 2011. This product is named as dotPeek. This is what they are saying:

dotPeek is a new free .NET decompiler from JetBrains, the makers of a wide array of developer productivity tools.

Browsing namespace hierarchies
All you need to do is drag and drop the assembly in the tool and just browse through the namespace hierarchies to find the required type.


Browsing Type Hierarchies
Type hierarchies can also be navigated using the same assembly explorer. You can not only see the decompiled version of the type but also its inheritors and base classes. It also displays the interfaces that the type is implementing.


The type hierarchies can also be viewed in Assembly explorer.


Find Usage of a symbol
We can find the usage of a symbol like we do in visual studio. But definitely it would be able to get the usages in just the assembly loaded.


This can be downloaded from here:

http://confluence.jetbrains.net/display/NETPEEK/dotPeek+Early+Access+Program

Thursday, March 15, 2012

Visual Studio hosting WCF Services using WCF Service Host

In this post we are going to be creating a simple WCF Service library project. We are going to be hosting this using Visual Studio Service host. We are going to see what various options are available to launch a WCF Service using Visual Studio including how we can test it using WCF Service Client. We are also going to be using Process Explorer to see how these supporting tools are used by Visual Studio.

When we create a WCF class library project, then Visual Studio creates a default WCF service for us with default template. It creates the following in the project.
  1. Adds the relevant assembly reference to the project. This includes System.Runtime.Serialization.dll and System.ServiceModel.dll.
  2. Adds a WCF Service containing a simple method. The class implements a contract added separately. The method (defined as operation contract)
  3. Adds a interface decorated with [ServiceContract] attribute. This also has a method decorated with [operationContract] attribute. This is the same interface implemented by the above class.
  4. Adds a class decorated with [DataContract] attribute. This type is used as a parameter in the operation contract method of above service contract.
  5. Adds app.config to the project. The configuration has the details of the exposed WCF service.

  6. See the properties of a WCF Service library project. There is an additional WCF options tab added.



    There is only one configurable option for the WCF service. When checked, Visual Studio automatically launches WCF Service Host utility hosting the service even when there is another start up project in the solution. This is a Visual Studio supporting tool and gets installed with Visual Studio installation in the following path in your Windows 7 computer.

    C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\

    This is available as follows:


    Let's download Process Explorer to see the details about WCF Service Host process from the following technet link:

    http://technet.microsoft.com/en-us/sysinternals/bb896653

    When launched, WCF Service host is available in system tray as follows:


    The tray icon can be used to launch the tool's interface. The interface has the details about hosted service.


    • If the WCF class library project is the start-up project then the service host is launched with relevant start-up arguments to use WCF Test Client as the client tool for the hosted service. The service host takes care of launching the client tool. We can use Process explorer to see the start-up argument of service host process.

      It is basically launched with the following start-up arguments.
      /service:C:\Users\shujaat\documents\visual studio 2010\Projects\InstituteApp\Institute.Data\bin\Debug\Institute.Data.dll
      /config:C:\Users\shujaat\documents\visual studio 2010\Projects\InstituteApp\Institute.Data\bin\Debug\Institute.Data.dll.config
      /event:dc8e4802-046c-4134-97b3-0d940ab3ee82 
      /client:"WcfTestClient.exe
      
      Specifying the switch for client launches the WCF Test Client after the service is hosted in WCF Service Host tool. The WCF Test Client is launched with the start-up arguments specifying the service details.


    • When the service project is not selected as a start-up project then Visual Studio just launches the WCF Service host with the details of the service being hosted. The start-up arguments to launch WCF Service host are as follows:
      /service:C:\Users\shujaat\documents\visual studio 2010\Projects\InstituteApp\Institute.Data\bin\Debug\Institute.Data.dll
      /config:C:\Users\shujaat\documents\visual studio 2010\Projects\InstituteApp\Institute.Data\bin\Debug\Institute.Data.dll.config
      /event:56023077-b3b8-486d-8e62-ffc2ccf7cad7 
      We can see that all the parameters are same except the client is not expected to be launched so the client switch hasn't been specified.

Basically the additional start-up argument is the default start-up argument of WCF Service library project. It can be seen in the Debug tab of project properties. If we don't want the WCFTestClient to be launched when WCF Service runs as a start-up project then just remove this extra switch.


Download Code:

Wednesday, March 14, 2012

Entity Framework Code First - Visualizing Generated Model & Database

Aren't we always curious about finding out how model is generated from the entities we have defined in Code First. Since there are so many conventions involved, it always seems difficult to go to the database and see individual tables. Well, there are different ways which could make our life easier to understand the database generated and even the resulting model by the code first entities. Let's discuss about them.

This discussion would discuss how we can get a complete picture of the related entities in a Context and resulting database without. As they say, a picture is worth a thousand words. So, definitely, this would make our life easier to be managing those entities, their relationship and resulting databases.
  1. Database Diagrams
  2. Viewing Entity Data Model using Visual Studio Integration
  3. Generating model using EdmxWriter
Database Diagrams
Most SQL Client tools allow creation of diagrams for existing tables. We just need to reverse engineer the database and select the tables we need. In the diagram, we can see the details of the selected tables. We can also see the foreign key relationships between them. SQL Server Management Studio also has such support. Just right click the Database Diagrams folder under your database in Object Explorer and select New Database Diagram.


You should see following dialog providing the list of all the tables in the database. Here you can select all the tables that you want to include in the diagram and click Add button. For our database, we should see the following list of tables.


As we hit the button, a new database diagram is created and shown. It has the tables as selected in the previous step. It also has the foreign key relationship details between the selected tables.


Visualizing Model using Entity Framework Power Tools
We can also visualize the expected model during design time using Entity Framework Power Tools. It is a Visual Studio Extension which can be installed using online extension library download feature of Visual Studio as follows:


After installation, if you select a class file in the solution explorer the following context menu is displayed allowing the view of the expected model.


If the selected file contains a sub-class of DbContext then it generates a read-only model listing all the entities as expected to be generated at run-time.


Persisting Generated model as *.edmx file
We can also support persisting the generated model at run-time. Entity Framework ... has added a new type to the framework just to support this requirement. This is called EdmxWriter. It can use an XmlWriter to persist the generated model as in the below code:
using (var context = new InstituteEntities())
{
    XmlWriterSettings settings = new XmlWriterSettings();
    settings.Indent = true;

    using (XmlWriter writer = XmlWriter.Create(@"Model.edmx", settings))
    {
        EdmxWriter.WriteEdmx(context, writer);
    }
}
Here XmlWriter and XmlWriterSettings are from System.Xml namespace. You would be needing to import the namespace in the class file before using them. After the above code is executed, we should see Model.edmx file created in the output directory.


We can view this file in Entity Designer in Visual Studio.

Saturday, March 10, 2012

Entity Framework Code First - Connection with Database

This post of part of a series of posts in which we are discussing various features of entity framework code first. We have been building on an Institute project and adding stuff to it based on the feature discussed. You might have realized that we have never shown you the actual connection string, yet we have been interacting with database for persistence of the institute entities. In this post we will be discussing how we are doing that without even specifying the connection string. We will also be discussing how we can customize this default behavior.

Building Connection String:
As we have discussed, a big part of entity framework code first is learning the various conventions it uses. It also has such conventions while interacting with database. The first convention is about finding connection string from the app.config and building it if one is not found there.

Which Connection String to use from config?
After building the conceptual model, Entity framework Code first API tries to locate the database. In order to connect to it, it needs the connection string. For this purpose, it uses the name of DbContext or a suggestion from DbContext. It can use either of the type name or the fully qualified name of DbContext. Let's use this connection string in the app.config.
<connectionStrings>
  <add name="InstituteEntities"
       providerName="System.Data.SqlClient"
       connectionString="Server=.\SQLExpress;
                          Trusted_Connection=true;
                          Database=EFCodeFirstDatabaseCreation.Entities.InstituteEntities"/>
</connectionStrings>
This would result in connecting to EFCodeFirstDatabaseCreation.Entities.InstituteEntities database on the local system's instance name SQLExpress. Since System.Data.SqlClient provider is used then it must be a SQL Server instance.


Let's see what happens if we use the fully qualified name of DbContext as name of our connection string in the app.config.
<connectionStrings>
  <add name="EFCodeFirstDatabaseCreation.Entities.InstituteEntities"
       providerName="System.Data.SqlClient"
       connectionString="Server=.\SQLExpress;
                          Trusted_Connection=true;
                          Database=EFCodeFirstDatabaseCreation.Entities.InstituteEntities"/>
</connectionStrings>
This would result in the connection as follows:


If you want the cat to really be killed then you must be curious to know what if we use both of them in app.config. Although one would never use this in a real scenario but it really doesn't hurt in finding out. Belive me, "Ignorance is not a bliss". Let's remove the database from the SQL Server instance. Let's first remove the already existing database.


Now we run the application. Since the framework can not decide between which connection string to use, it throws an exception as follows:


Let's see the details of the exception. The framework really got confused to build the connection and resulted in the exception.


As we start debugging we realize the following exception while construction of DbContext instance.

No Connection string found in config?
Now we discuss what if there is no connection string found in the app.config based on the criteria used by EF Code first. The framework still doesn't give up. Now it assumes that there is a SQL Server instance running on the local machine with name SQLExpress. This is the default instance name when SQL Server Express is installed. This is fairly good assumption that the Microsoft platform developers would have SQL Server Express installed on their machines and it would be installed with the default instance name as we (developers) are also fairly lazy to change the default options in installers. Let's comment out the connection strings in app.config and see what happens. When we run the application, it seems that the DbContext is instantiated successfully. Basically, based on the SQL Server Express instance, it has automatically created a database for us using the fully qualified name of DbContext specialization type.


Suggesting Connection String Name:
As we discussed in previous discussion that the framework uses the DbContext type name to look up the connection string in app.config. So we must be keeping the name of the connection string to be the same as the type name of the DbContext. What if we want to keep a specific name. We might be following different naming conventions for type names and configs. They might also be managed by different teams altogether. In this case, how can we help the framework to still be able to use the specific connection string?

Basically DbContext does support that, we just need to use the relevant DbContext constructor when it is being initialized. Let's update the constructor of InstituteEntities to be use the particular base type constructor.
public InstituteEntities() : base("instituteConnectionString")
{   
    this.Configuration.ProxyCreationEnabled = true;
    this.Configuration.AutoDetectChangesEnabled = true;
}
Now the default constructor of InstituteEntities would be using the specific constructor of the base class to specify the connection string name in app.config. Let's update the app.config and add the expected connection string as follows:
<connectionStrings>
  <add name="instituteConnectionString"
       providerName="System.Data.SqlClient"
       connectionString="Server=.\SQLExpress;
                          Trusted_Connection=true;
                          Database=SuggestedInstituteDatabase"/>
</connectionStrings>
If the framework would use the above connection string then it would look for a database named SuggestedInstituteDatabase. If the database is not found then it would create it for us. Let's run the application now. There are no exceptions. Now go to the SQL Server Management Studio and refresh the Databases. That's right, it has created the expected database for us.


Suggesting Database name but still using default configuration:
What if we don't want to specify the app.config but we still want to use the specific database name. The framework also supports that. As a matter of fact, the same DbContext constructor is used for that. The string parameter can be either the connection string name in the app.config. If not found, then it would be creating a database for us in the default SQL Server Express instance on local machine. Let's look at the documentation of the particular constructor of DbContext.


Before going any further, just comment the connection string in app.config. You can also delete the particular database in the SQL Server instance.Let's update the constructor to specify the Database name instead.

public InstituteEntities()
    : base("SuggestedInstituteDatabase")
{   
    this.Configuration.ProxyCreationEnabled = true;
    this.Configuration.AutoDetectChangesEnabled = true;
}
Now run the application and see the created database in SQL Server Management Studio. [If you are already running SQL Server Management Studio then you would need to refresh the databases.


Using Encrypted Connection String
The world is not so simple. There are extra curious people who want to see how we have done what we have done. They want to do it for fun or monetary or political gains. We want to keep our systems protected from their curious nature. The easiest option is to keep the connection string encrypted so, even if, they are able to access the app.config, the could not find the connection details from the connection string.

Now this requirement would push us how the entity framework resolves the connection string.

Using pre-instantiated DbConnection to construct DbContext
DbContext provides us with various constructors. As we know we can specify what base class constructor to pick when a particular sub-type constructor is used for instantiating the sub-type. We can use the DbContext constructor which allows us to pass the pre-instantiated DbConnection to be used for DbContext initialization. The below code is using the same approach.
public InstituteEntities() : 
    base(new SqlConnection(Constants.ConnectionString), false)
{
    //DbContext sub-type constructor initialization
}
Since we are using SQL Server database to hold the entities, we are using SqlConnection instance to be passed to DbContext constructor. We need to specify what connection string to use for this DbConnection. The above code is getting the connection string from static member ConnectionString from Constants class. Now it is up to us how we want to load / build the value of ConnectionString.
public static class Constants
{
    public static string ConnectionString
    {
        get  { return GetDecryptedConnectionString();  }
    }

    private static string GetDecryptedConnectionString()
    {
        return @"Server=.\SQLExpress;Trusted_Connection=true;Database=SuggestedInstituteDatabase";
    }
}
In the above code, ConnectionString is getting the value from GetDecryptedConnectionString() method. This is here, in this method, that we can load / build the connection string. If this is encrypted then we can decrypt it and return to the calling code. In order to test this code, let's delete the SuggestedInstituteDatabase from the local SQL Server instance. When we run the application, the database should be created automatically. This is created by EF Code First using the connection details passed in the constructor.


EF Code First Provider Model
Like ADO.net, Entity Framework Code First uses provider model for database management systems. It provides a certain framework for third party library developers to develop the providers that it can use to work with a particular database. There is default provider for SQL Server available in the framework. For working with other database, you would need to download the specific provider libraries and use them in your code instead. Let's not waste any time on it and use the default provider as we still want to use SQL Server. We just want to modify this so that it could use the encrypted connection string.

As we discussed above, the providers must be providing the implementation of various abstractions which we can use in our code. One such type is about connection factories. As its name implies, this would be used to create connection for the particular Database Management System [DBMS].
class EncryptedIDbConnectionFactory : IDbConnectionFactory
{
    #region Private Fields

    IDbConnectionFactory _connectionFactory;

    #endregion

    #region Constructors

    public EncryptedIDbConnectionFactory(IDbConnectionFactory dbConnectionFactory)
    {
        if (dbConnectionFactory == null)
        {
            throw new ArgumentNullException("dbConnectionFactory can not be null");
        }

        _connectionFactory = dbConnectionFactory;
    }

    #endregion

    #region IDbConnectionFactory implementation
    public DbConnection CreateConnection(string nameOrConnectionString)        
    {
        //decryption of connection string
        string decryptedConnectionString = 
            GetDecryptedConnectionString(nameOrConnectionString);

        return _connectionFactory.CreateConnection(decryptedConnectionString);
    }
    #endregion

    #region Private Methods
    private string GetDecryptedConnectionString(string nameOrConnectionString)
    {
        //use some encryption library to decrypt
        return nameOrConnectionString;
    }
    #endregion
}
Using connection factory like this would still use the functionality of the existing factory to create database connection. We are just providing a functionality that the connection string passed should be decrypted before it even goes to build the connection. It is the implementation of Decorator design pattern. Here you can use an encryption library to decrypt the connection string in GetDecryptedConnectionString method. For keeping the example simple, we are just returning the same string back to the calling code. Consider this your assignment to be using the appropriate encryption library.

We need to inform the EF Code first framework to use the new database connection factory instead. This is done in application initialization code before DbContext is even initialized.
Database.DefaultConnectionFactory = 
                new EncryptedIDbConnectionFactory(Database.DefaultConnectionFactory);
Now how is this approach different than the previous one? Basically, in this approach the construction of DbConnection is still delegated to the DefaultConnectionFactory. We are just helping it resolve the connection string encryption as the default factory expects it unencrypted. It can also use all the possible conventions based on Entity Framework Code First. This approach is also very extensible to add various features to the connection factory without actually extending it. Now it is up to the requirement which particular feature we want, we can decorate the factory with those additional decorators and Zindabad!!! Like we can add tracing or caching decorators and use it with the default connection factory. Now when we run the application, we should be seeing the exact database created as the previous example.

Download Code

Wednesday, March 7, 2012

Defect Density as Estimation tool

I just started guest blogging on Headspring as guest blogger. They just published my article about Defect Density as Estimation Tool. You can find it here:

http://www.headspring.com/2012/03/defect-density-estimation

Monday, March 5, 2012

Entity Framework Code First - Change Tracking

In this post we will be discussing about change tracking feature of Entity Framework Code First. Change tracking allows Entity framework to keep track of all the changes in entities' data. It might involve adding new entities to entities collection or modifying or removing existing entities. These changes are kept at DbContext level. All changes are lost if they are not saved before destroying the DbContext instance.

By default, Entity framework Code First registers all changes as the occur. When it's time to save those changes it just looks at this information and updates the database tables based on this registered information. Additionally, it keeps a snapshot of entities as they are loaded from Database or when they were last saved to the Database. This snapshot of entities and automatic change tracking are used to push the entities changes to the database.

Enabling Change Tracking
Automatic Change tracking is enabled by default. Disabling it would not trigger the DbContext update for each change in the entity. There are specific instances when DbContext would update the DbContext with the changes. This includes explicit call to SaveChanges() method of DbContext. Change tracking can be enabled / disabled by setting AutoDetectChangesEnabled to true / false respectively for DbContext.
public InstituteEntities()
{
   this.Configuration.AutoDetectChangesEnabled = true;
}
This ensures that all the changes involved with any entity in the context are tracked by the framework. The framework maintains the state of entities. It uses this to determine the changes needed to be pushed to database when SaveChanges() is called. Disabling change tracking would still allow us to check the old and current values of an entity but it would keep the state as UnChanged until the changes are detected. We need to manually call DetectChanges() on DbContext to update them. There are instances in which it is called implicitly by Entity Framework API. Since it would check all the entities of all types, for which change tracking is enabled, to verify if they have any changes in their data. If so, it changes their state as Modified. It helps the framework to push all the entities with Added, Modified and Detached states when SaveChanges() is called on DbContext. Here SaveChanges() is an implementation of UoW (Unit of Work) pattern descibed by Martin Fowler.

Change Tracking Proxies Vs Snapshot Change Tracking
Entity Framework creates a snaphot of all entities data when they are loaded from Database. When it needs to save these entities to the database, it compares this snapshot of all entities to their current state. It then updates the database based on the state of these entities. It might add, update or delete the entities based on their states. Saving entities is the implementation of Unit of Work (UoW) pattern described by Martin Fowler. Since it uses the states of entities to perform the specific CRUD [CReate, Update, Delete] operation, the state must be updated before the entities are saved. In order to save developers, the EF implcitly updates the states before saving them, if required. This might be very costly if there are many changes to the entities. In order to optimize this, it is better to call DbContext.DetectChanges() when it is safe to do so. After pushing these changes to the database, another snapshot is taken which is used as OriginalValues of these entities.

There are also other instances when DbContext.DetectChanges() is implicitly called by the framework. According to MSDN, they are as follows:
  1. The Add, Attach, Find, Local, or Remove members on DbSet
  2. The GetValidationErrors, Entry, or SaveChanges members on DbContext
  3. The Entries method on DbChangeTracker
This is unlike ObjectContext API where only SaveChanges() would implicitly call DetectChanges(). In all other instances we need to manually call it if so desired.

Entity States
An entity goes through various states throughout its lifetime. It is based on various operations performed to change its properties. The operations on DbContext can also result in updating the state of an entity. It can roughly be presented in a state diagram as follows:


These are the main state transitions which you might expect in realistic scnenarios. There are a few other state transitions too which are not very realistic e.g. If an entity is added using DbSet.Add() and the entity is already existing then the state of the entity changes to Added. An entity is an object and it is semantically wrong. In a typical implementation, one would expect an exception in this case. Change tracking keeps an entity's state always updated. If we modify any property of an entity its state changes to Modified.

Let's see the effect of enabling / disabling the auto-detection of changes of entities. Let's execute the same code block under both conditions and see the effect of setting the auto-detection to an appropriate value. Here we are updating the DepartmentName of the first department found in the Departments entities collection and setting it to an updated value. We are using DbContext to get the original and updated value of the particular Department entity. Then we are printing the original and updated value of the Department entity along with the state information of these entities. The generic DbContext.Entry() method lets us get the DbEntityEntry object for a particular entity. This is the central type in DbContext API. Once we get it, we can access OriginalValues and CurrentValues properties. Both of them are of type DbPropertyValues. It is a collection of all the properties of an underlying entity or a complex object. Now we can use GetValue<T> method to get the value of any property by providing its name.
using (var context = new InstituteEntities())
{
    var department = context.Departments.First<Department>();
    department.DepartmentName = "Computer & Information Systems Engineering";

    DbEntityEntry<Department> departmentEntry = context.Entry<Department>(department);
    DbPropertyValues originalDepartment = departmentEntry.OriginalValues;
    DbPropertyValues updatedDepartment = departmentEntry.CurrentValues;
    EntityState state = context.Entry<Department>(department).State;

    Console.WriteLine(
        string.Format("State: {0}, Old Value: {1}, New Value: {2}",
                        state, originalDepartment.GetValue<string>("DepartmentName"),
                        updatedDepartment.GetValue<string>("DepartmentName")));
}

Here we have enabled auto detection. As you can see updating Department's name updates the state of the entity as Modified.
public InstituteEntities()
{
    this.Configuration.AutoDetectChangesEnabled = true;
}


On the contrary, if we disable change tracking the state of an entity is not updated until it is caused. We can do that by calling DbContext.DetectChanges(). It is also implicitly called by EF when SaveChanges() is called. In the following example, we are disabling change tracking. You can see that, although, we can still see old and new values of different properties of an entity, it keeps its state as Unchanged.
public InstituteEntities()
{
    this.Configuration.AutoDetectChangesEnabled = false;
}


Note: As you can notice that, although the state of the entity is affected by updating the auto-detection but it's data seems to be reflecting the changes. This is due to the implicit call to DbContext.DetectChanges() by DbContext.Entry() as discussed above.

Capturing Data Changes in Code
In order to capture any changes with the data, Entity Framework has provided a comprehensive API around it. A number of types are provided. They are mostly in System.Data.Entity.Infrastructure namespace in EntityFramework assembly. The main type that you would mostly be needing is DbEntityEntry. It is available in both generic and non-generic flavors. Using the generic version saves us from a lot of typecasting later in the code. We can get the DbEntityEntry for any entry. It allows us to check the original values of the properties of an entity. It also provides the state of entity. As we discussed above that this state would depend on a number of factors i.e. wheter the change tracking is enabled or DbContext.DetectChanges() has been called. Now how to get DbEntityEntry for a particular entity. We seem to have a few options here.

Using DbContext.Entry<TEntity>
We use this we are already holding the entity object and we need to obtain information about entity. In the following example we are getting an arbitrary department from the DbContext. We are updating the value of DepartmentName property. DbEntityEntry allows us to get the old and new values of an entity's property as DbPropertyValues. This can be used to get the value of any property using its GetValue method. As you have seen above:
using (var context = new InstituteEntities())
{
    var department = context.Departments.First<Department>();
    department.DepartmentName = "Computer & Information Systems Engineering";

    DbEntityEntry<Department> departmentEntry = context.Entry<Department>(department);
    DbPropertyValues originalDepartment = departmentEntry.OriginalValues;
    DbPropertyValues updatedDepartment = departmentEntry.CurrentValues;
    EntityState state = context.Entry<Department>(department).State;

    Console.WriteLine(
        string.Format("State: {0}, Old Value: {1}, New Value: {2}",
                        state, originalDepartment.GetValue<string>("DepartmentName"),
                        updatedDepartment.GetValue<string>("DepartmentName")));
}

Using DbContext.ChangeTracker.Entries<TEntity>
This is another option to get the DbEntityEntry for an entity. We generally use this when we are not holding on the the actual entity object. This also has its generic and non-generic versions but they are operationally different. The generic version provides DbEntityEntry objects for entities of a given type tracked by the DbContext. On the other hand the non-generic version provides them for ALL entities tracked by the system, which might not be needed most of the time. Additionally, the generic version returns the generic version of DbEntityEntry and non-generic version returns the non-generic one. In the following example, we are practically doing the same thing as the above example but we are getting the entries using DbContext.ChangeTracker. It is an IEnumerable so we can use an Iterator to play with individual values.
using (var context = new InstituteEntities())
{
    var department = context.Departments.First<Department>();
    department.DepartmentName = "Computer & Information Systems Engineering";

    DbChangeTracker changeTracker = context.ChangeTracker;
    IEnumerable<DbEntityEntry<Department>> departmentEntries = 
                                        changeTracker.Entries<Department>();

    foreach (DbEntityEntry departmentEntry in departmentEntries)
    {
        DbPropertyValues originalDepartment = departmentEntry.OriginalValues;
        DbPropertyValues updatedDepartment = departmentEntry.CurrentValues;
        EntityState state = context.Entry<Department>(department).State;

        Console.WriteLine(
            string.Format("State: {0}, Old Value: {1}, New Value: {2}",
                            state, originalDepartment.GetValue<string>("DepartmentName"),
                            updatedDepartment.GetValue<string>("DepartmentName")));
    }
}

Change Tracking for Individual members of an Entity
In the above code, we saw how we can get the DbEntityEntry with current and old values. Code first lets us more fine grained interfaces through which we can capture individual properties of an entity. There are different types provided for this. All of these classes inherit from DbMemberEntry<TEntity>. It is an abstract class. All scalar properties of an entity use DbPropertyEntry. The complex properties uses futher specialized version of this and it uses DbComplexPropertyEntry. DbReferenceEntry and DbCollectionEntry are used by reference and collection based navigation properties respectively. We can present the relationship between these types as follows:


using (var context = new InstituteEntities())
{
    var department = context.Departments.First<Department>();
    department.DepartmentName = "Computer & Information Systems Engineering";

    DbChangeTracker changeTracker = context.ChangeTracker;
    IEnumerable<DbEntityEntry<Department>> departmentEntries =
                                        changeTracker.Entries<Department>();

    foreach (DbEntityEntry<Department> departmentEntry in departmentEntries)
    {
        DbPropertyEntry<Department, string> deparmentNameEntry = 
            departmentEntry.Property<string>((d) => d.DepartmentName);

        string oldDepartmentName = deparmentNameEntry.OriginalValue;
        string modifiedDepartmentName = deparmentNameEntry.CurrentValue;

        EntityState state = departmentEntry.State;

        Console.WriteLine(
            string.Format("State: {0}, Old Value: {1}, New Value: {2}",
                            state, oldDepartmentName,
                            modifiedDepartmentName));
    }
}

DbEntityEntry Vs ObjectStateEntry
Before there were humans in this planet we call earth, there used to be a completely different world. There used to be a different creatures, some of them we call as Dinosaurs. But somehow they got destroyed and a new world was created. New species came into being. Even if we don't indulge into the debate of evolution Vs Intelligent design then there has been continuous evolution of human thoughts. We are learning about various hidden secrets of the universe and helping others learn. Similarly, before DbContext API, there used to be ObjectContext API. For some reason the all-knowing Creator of the framework [Microsoft] decided to get rid of the older, more complicated ObjectContext world and hence new DbContext API was born. This is definitely an intelligent design but the new species are also evolving and you see different versions like 4.2, 4.3 and so on. The problem is that they can co-exist. There has been a door to go back in time using IObjectContextAdapter to get ObjectContext through DbContext and here the fun begins. Now we can use the features of both the world in the same space and time. ObjectContext API used to have a similar feature like DbEntityEntry, it was ObjectStateEntry. Don't be surprised if you find them in older code or see them co-exist with new DbContext API. But don't use them in any new code after you have release version of tools supporting DbContext API available unless there is any legitimate reason.

Complex Type and Change Tracking
Like lazy loading, change tracking is also not supported for complex types. This is because the complex types are not real entities. They are syntactic sugar to group a number of fields. Each member of a complex type would be created as a column in the main entity. It has no primary key. The complex type based property is itself considered for change tracking. So if we assign a new instance to a complex type reference, it is tracked automatically. Let's make changes to CourseLocation and LocationAddress to support proxy creation. [http://msdn.microsoft.com/en-us/library/dd468057.aspx]
namespace EFCodeFirstDatabaseCreation.Entities
{
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;

    public class CourseLocation
    {
        public virtual int CourseLocationId { get; set; }
        public virtual string LocationName { get; set; }
        public virtual LocationAddress Address { get; set; }
        public virtual ICollection<Course> CoursesOffered { get; set; }
    }

    public class LocationAddress
    {
        public virtual string StreetAddress { get; set; }
        public virtual string Apartment { get; set; }
        public virtual string City { get; set; }
        public virtual string StateProvince { get; set; }
        public virtual string ZipCode { get; set; }
    }
}
Let's enable proxy creation and automatic change tracking by DbContext as follows:
public InstituteEntities()
{
    this.Configuration.ProxyCreationEnabled = true;
    this.Configuration.AutoDetectChangesEnabled = true;
}

Let's make some changes in the properties of a complex type for an entity and see how this affects the state of the entity itself. We can not check the state of a complex type directly using DbContext.Entries() or DbChangeTracker.Entries() as DbContext.ChangeTracker.Entries().
using (var context = new InstituteEntities())
{
    var courseLocations = context.Set<CourseLocation>();
    foreach (var location in courseLocations)
    {
        Console.WriteLine("LocationName: {0}, City: {1}", 
            location.LocationName, location.Address.City);
        
        location.Address.City = string.Format("Great City of {0}", location.Address.City);
        
        Console.WriteLine("Updated LocationName: {0}, City: {1}",
            location.LocationName, location.Address.City);
    }

    //Complex types not directly tracked 
    var trackedLocationAddressEntities = context.ChangeTracker.Entries<LocationAddress>();
    Console.WriteLine("# Tracked LocationAddress: {0}", trackedLocationAddressEntities.Count());

    var trackedCourseLocations = context.ChangeTracker.Entries<CourseLocation>();
    Console.WriteLine("# Tracked CourseLocations: {0}", trackedCourseLocations.Count());

    string courseLocationEntityStates = 
        string.Join(",",
            trackedCourseLocations.Select(l => l.State)
                .Select<EntityState,string>(n => Enum.GetName(typeof(EntityState), n))
                    .ToArray<string>());

    Console.WriteLine("Tracked CourseLocation States: {0}", courseLocationEntityStates);
}
This would result in the following output:


Interesting...But isn't that contrary to what we just discussed? i.e. there is no automatic change tracking for complex type. Yes, that is also true. But how would we justify this output with this statement. Let me explain. Basically, the state update that we see for CourseLocation entity after updating the values of LocationAddress is not because of automatic change tracking. It is because of using DbContext.ChangeTracker.Entries to get the entity's states. It also has an implicit call to DbContext.DetectChanges() as we discussed above. So, snapshot change has been pushed which has resulted in this behavior. Let's verify this with ObjectContext API to see if that is the case. We update the same method as follows:
private static void TestMethod5()
{
    using (var context = new InstituteEntities())
    {
        var courseLocations = context.Set<CourseLocation>();
        foreach (var location in courseLocations)
        {
            Console.WriteLine("LocationName: {0}, City: {1}", 
                location.LocationName, location.Address.City);
            
            location.Address.City = string.Format("Great City of {0}", location.Address.City);
            
            Console.WriteLine("Updated LocationName: {0}, City: {1}",
                location.LocationName, location.Address.City);
        }

        Console.Write("Using ObjectContext API to get EntityState");
        Console.WriteLine("*************************************");
        foreach (var location in courseLocations)
        {
            var ocAdapter = ((IObjectContextAdapter)context).ObjectContext;
            var state = ocAdapter.ObjectStateManager.GetObjectStateEntry(location).State;
            Console.WriteLine("Location: {0}, City: {1}, EntityState: {2}", 
                location.LocationName, location.Address.City, state);
        }
        
        Console.WriteLine("*************************************");                
        Console.Write("Using DbContext API to get EntityState");
        Console.WriteLine("*************************************");                

        //Complex types not directly tracked
        var trackedLocationAddressEntities = context.ChangeTracker.Entries<LocationAddress>();
        Console.WriteLine("# Tracked LocationAddress: {0}", trackedLocationAddressEntities.Count());

        var trackedCourseLocations = context.ChangeTracker.Entries<CourseLocation>();
        Console.WriteLine("# Tracked CourseLocations: {0}", trackedCourseLocations.Count());

        string courseLocationEntityStates = 
            string.Join(",",
                trackedCourseLocations.Select(l => l.State)
                    .Select<EntityState,string>(n => Enum.GetName(typeof(EntityState), n))
                        .ToArray<string>());

        Console.WriteLine("Tracked CourseLocation States: {0}", courseLocationEntityStates);
    }
}
Now you can verify that when we get the states using ObjectContext API, it shows them as UnChanged. This is because ObjectContext API does not implicitly call DetectChanges(). But when we use DbContext API, it shows as Modified, which proves our point.

We can also use ComplexProperty method of DbEntityEntry to get the changes in complex property.
Address currentValues = context.Entry(user)
                                   .ComplexProperty(u => u.Address)
                                   .CurrentValue;


Download Code: