When Microsoft first released the Entity Framework, agile developers roundly criticized it. These developers hold the tenets of domain-driven development and testability very high. The classes generated from the Entity Data Model (EDM) are very tightly bound to the Entity Framework APIs by either inheriting from the EntityObject or implement interfaces that allow the classes to participate in change tracking and relationship management.

The problem with this is that it is extremely difficult to separate the concerns of your application into smaller pieces of logic to make it more maintainable. Additionally, it is difficult to write unit tests with EntityObjects. Many of the methods that need to be tested perform some type of interaction with the database. In unit testing, you need to emulate this persistence. In other words, instead of literally querying the database, a test might supply some fake data to a class, or instead of sending data to the data store, a test might say “OK, let’s pretend that part just happened and we’ll move on now.”

The Entity Framework team listened to and learned about these and other show-stoppers from the agile community and added a number of new mechanisms for supporting agile development.

One of these is support for Plain Old CLR Objects (POCO). POCOs are classes that remain free from a backing infrastructure, such as Entity Framework. A POCO class would not inherit from Entity Framework’s EntityObject. But as you’ve seen, the EntityObject performs all of the important work for providing relationship and change tracking information to the context. In order to remove the dependency on EntityObject, the Entity Framework gained some new functionality that allows the ObjectContext to acquire relationship and change tracking information from classes that do not inherit from EntityObject. In fact, as you’ll see, it can do so with classes that have no knowledge at all about the Entity Framework.

In addition to POCO support, the team added two other important features for developers who do not want to be tied up with the concerns of the database. One is support for model-first development, which allows developers to begin a project with a model and use that model to create a database. The other is called code-first development. Code first is still a work in progress and is available as part of a separate download called the Entity Framework CTP.

In this article, you’ll learn the basics of how to create and work with POCOs in Entity Framework. There are two avenues to the POCO support. You’ll begin with the simplest form, which requires a bit of extra work on the part of the ObjectContext. Then you’ll learn about another form of POCO support that lets the POCOs behave similarly to EntityObjects at runtime.

You’ll begin with the simplest form, which requires a bit of extra work on the part of the ObjectContext. Then you’ll learn about another form of POCO support that lets the POCOs behave similarly to EntityObjects at runtime.

Creating POCO Classes

POCO classes work in conjunction with a model in that they must mirror the entities in the model.

To begin this discussion, I’ll use SampleModel, which is a very simple model and database. See the sidebar, “Get the Sample Databases” for information on downloading this database. Let’s create the model and then the classes, as it will be helpful to point out how they relate to one another. It is just as likely that you will create the classes first or even that they will pre-exist.

** NOTE: ** The POCO and related classes created in this article are built manually. If you are starting with a model, it makes much more sense to use a T4 template to generate the POCO classes from the model.

Start by creating a new Console Application project. Then add a new Entity Data Model based on ProgrammingEntityFrameworkDB1. Name the EntityContainer POCOEntities and select all tables. Now you are back to your simple model.

There are a few rules that you need to follow when creating classes that will interact with Entity Framework. One is that the class and property names should align with the model. Another is that every property in the model entity must be represented in the class; this includes scalar properties and navigation properties. For this example, we’ll just follow the existing model, shown in Figure 1, to determine the names and structure of the classes.

Figure 1: The simple model that we’ll use in the following examples.
Figure 1: The simple model that we’ll use in the following examples.

Add two new class files to the project, called Contact.cs and Address.cs. Next, add properties to the Contact class for every property in the Contact entity.

Be sure to mimic the names as well as the types, with one caveat. The Addresses navigation property returns an EntityCollection, which is a very constrained type. In your class, use an ICollection to return the related collection. An ICollection will give you ultimate flexibility when you consume the class.

Here is the code snippet for the Contact class. Notice that it uses auto-implemented properties, which don’t require a backing variable to retain their values.

public Contact()
{
  Addresses = new List<Address>();
}
public int ContactID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Title { get; set; }
public System.DateTime AddDate { get; set; }
public System.DateTime ModifiedDate { get; set; }
private string Gender { get; set; }
public ICollection<Address> Addresses
 { get; set; }
}

It is perfectly acceptable to have additional properties, such as Gender, and methods in the POCO classes. As long as you minimally include the entity properties, the classes will work within the Entity Framework.

Now that you have your own classes, there is no need for the model to generate classes. You can turn off the code generation.

Open the model in the Designer. In the Properties window for the model, change the Code Generation Strategy property from Default to None. As you learned in the previous chapter, the class file attached to the model will still exist but will contain only a comment as a reminder that the code generation from the model has been disabled.

For the sake of this simple demo, I am having you put everything into a single project. This is not the proper way to architect this type of solution, but is a simpler way to be introduced to the basic concepts.

Create a new class called Entities and add the code in Listing 1. This emulates ObjectContext classes that are in earlier chapters of the book from which this article is excerpted.

The Entities class inherits from ObjectContext just as the other Entities classes you have seen thus far. The class constructor uses the signature of ObjectContext, which takes in the name of the EntityConnection string in the app.config file as well as the name of the EntityContainer in the model. As with the other Entities classes, this class contains read-only properties that return an ObjectSet of each type that you want to work with. The fields for these ObjectSet properties are instantiated in the class constructor. Remember, this only defines the ObjectSet but does not execute a query.

Verifying the POCOs with a Query

Now you can write your first queries to see how this all fits together.

In the application’s main module, add the following code, which will instantiate your new ObjectContext, query for all of the contacts, eager-load their addresses and then look at the addresses for a single contact.

private static void QueryPOCOS()
{
  using (Entities context = new Entities())
  {
    var query = from c in context.Contacts
      .Include("Addresses") select c;
    var contactList = query.ToList();
    int contactCount = contactList.Count;
    Contact contact = contactList.Where
      (c => c.Addresses.Any()).First();
    int addressCount = contact.Addresses.Count;
  }
}

If you debug through this you’ll see that all of the contacts are returned to contactList and that the first contact has one address in its collection.

Change Tracking with POCOs

Keep in mind that there are two ways to use POCOs. You are starting here with the simplest form. The chapter from which this article is excerpted also contains an example showing a very different way of interacting with the ObjectContext.

When you perform a query that results in POCO entities, the ObjectContext creates ObjectStateEntry objects for each result just as it does with an EntityObject. However, classes that inherit from EntityObject interact continuously with the ObjectContext, and therefore the context is able to keep track of the state of the classes as well as their relationships to one another.

POCOs do not communicate back to the context. Therefore, the context needs at some point to take a look at the POCOs and synchronize their data with the ObjectStateEntry objects that represent them. The ObjectContext class has a method called DetectChanges that satisfies this purpose.

Understanding the Importance of DetectChanges

It is important to instruct the context to detect changes prior to constructing the various SaveChanges commands when you want to send any changes made to your POCOs to the database. Otherwise, the ObjectStateEntry objects that the context is managing will not reflect the changes and no insert, update, or delete commands will be sent to the data store.

The SaveChanges method can take an optional SaveOptions parameter. One of the SaveOptions parameters is called DetectAllChanges. That option will force the context to call DetectChanges prior to the save logic. The default behavior for SaveChanges is that it will call DetectChanges, so you do not need to explicitly call the method or set the SaveOptions enum.

The default behavior for SaveChanges is that it will call DetectChanges, so you do not need to explicitly call the method or set the SaveOptions enum.

When working with EntityObjects, you can load related data explicitly with the EntityCollection.Load method or the EntityReference.Load method or take advantage of lazy loading to bring in related data without creating a new query. You won’t be able to do that with the POCOs you have just built. The navigation properties are no longer EntityCollections or EntityReferences so the Load method is unavailable. It is also the EntityCollection and EntityReference class that provides Entity Framework with its lazy loading capabilities. Without these types in your classes, you’ll need another mechanism for loading data after the fact.

Loading from the Context

As mentioned earlier, much of Entity Framework’s POCO support is based on new capabilities of ObjectContext. In .NET 4, ObjectContext has a new method called Load-Property and this is how you can explicitly load data with your POCOs.

Rather than call Load on a navigation property (e.g., contact.Address.Load), you can let the context perform the load with the following syntax:

context.LoadProperty<Contact>
  (firstContact, c => c.Addresses);

This overload uses generics to specify the type that will be loaded from (<Contact>) so that you can benefit from strong typing to use the lambda to specify which property should be loaded (c.Addresses). Because of the strong typing, IntelliSense will help you build the lambda expression. There are a few other overloads for this method which you can find at http://msdn.microsoft.com/en-us/library/dd382880.aspx. However, I prefer using the lambda.

Lazy Loading from a Dynamic Proxy

If you want to get lazy loading behavior for your POCO, you’ll need to leverage a trick provided by the Entity Framework runtime. By marking a navigation property as virtual (Overridable in Visual Basic), at runtime, Entity Framework will create a wrapper around that property that will turn it into either an EntityCollection or EntityReference (as appropriate). Therefore, if you have lazy loading enabled, it will simply work as expected.

Exploring and Correcting POCOs’ Impact on Two-Way Relationships

Developers working with EntityObjects have come to expect that two-way relationships are automatically available. For example, if you set an Address object’s Contact property, then that Address automatically becomes part of the Contact’s Addresses collection.

This behavior won’t happen on its own with your POCO classes. You’ll either need to write additional code to enforce the behavior or wait for a call to DetectChanges which will perform the “fixup” on your behalf.

There is more detailed information about this provided in the chapter from which this article has been excerpted.

Using Proxies to Enable Change Notification, Lazy Loading, and Relationship Fix-Up

As you read earlier, DetectChanges also forces the context to update the ObjectStateEntry objects that it uses for change tracking. When you call DetectChanges, the context takes a snapshot of the current state of the entities.

It is possible to force the entities to notify the context of changes so that you don’t have to wait until you (or the SaveChanges method) call DetectChanges.

You can do this by using a special feature of Entity Framework that enables classes to be wrapped by a special proxy class at runtime. To use this, you must mark every property in the class as virtual. In VB, this is Overridable.

C#
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }

VB
Public Overridable Property FirstName As String
Public Overridable Property LastName As String

At runtime, Entity Framework uses reflection to discover that you have marked the properties as virtual and it will create a DynamicProxy class on the fly, and then force it to inherit from your entity. Figure 2 shows the runtime proxy for a Contact class in the debugger.

Figure 2: A Contact object at runtime with a dynamic proxy wrapper.
Figure 2: A Contact object at runtime with a dynamic proxy wrapper.

The POCO template creates fairly simple classes with all of their properties marked as virtual, forcing them to use the DynamicProxy classes at runtime.

This proxy will add functionality to the runtime POCO class that has many of the same features as an EntityObject. But as you’ll see further on, it is not an EntityObject. It is something completely different.

Using proxies will automatically provide your classes with automatic relationship fix-up. At the same time, you also gain (or regain, as it were) many of the same behaviors provided by EntityObject, such as change notification and lazy loading.

You can read more details about how the runtime proxies enable automatic change notification, lazy loading and relationship synchronization in the chapter from which this article has been excerpted.

Using T4 to Generate POCO Classes

The book from which this chapter is excerpted demonstrated the use of T4 templates for code generation. It’s a lot of work to strip down Entity Framework’s default T4 template to force it to create simple objects. If you enjoy visiting the dentist, you might be interested in doing this work yourself. However, Microsoft has created templates that build Entity Framework POCOs from the EDMX. You could start with one of those and then tweak the template further to make it create classes that follow your desired pattern.

Unfortunately, the POCO templates are not “in the box” when you install Visual Studio 2010 RTM, but they are extremely easy to add in. Microsoft has created two pairs of POCO templates that are available from the Visual Studio 2010 Extension Manager. If you search for POCO in the Extension Manager, the first pair “Microsoft ADO.NET C# POCO Entity Generator” and “Microsoft ADO.NET VB POCO Entity Generator” are the most commonly used. The second pair is specifically for websites and I won’t be focusing on those. You can also go directly to http://www.visualstudiogallery.com/ to download Visual Studio extensions.

After you have installed a POCO Entity Generator extension, the ADO.NET POCO Entity Generator template will be an option when you choose to Add a Code Generation Item to your model. Selecting this template will, in fact, add two templates to your project. One template, with the extension BreakAway.Context.tt, is specifically for generating the ObjectContext class. The other, BreakAway.tt, will generate the entity classes. Figure 3 shows the two new templates in the Solution Explorer along with their automatically generated entity classes.

Figure 3: The two templates added by the ADO.NET POCO Entity Generator along with their generated classes.
Figure 3: The two templates added by the ADO.NET POCO Entity Generator along with their generated classes.

You’ll notice that both the context and the entity template are in the model project. If you are architecting to separate your application concerns, you probably do not want the entity classes in the same project with the model and persistence layer.

The POCO template creates fairly simple classes with all of their properties marked as virtual, forcing them to use the DynamicProxy classes at runtime. Additionally, it adds code to ensure that any foreign keys stay in sync with their related navigation property. And finally, there is code in there to maintain two-way relationship fix-ups similar to what you saw earlier in the chapter, although they use a class called FixUpCollection, which you’ll find in BreakAway.cs.

Listing 2 shows the complete listing for the generated Payment class. Notice the code in ReservationID that keeps the Reservation property in sync with the ReservationID foreign key. Additionally, you can see the fix-up code that adds or removes the Payment to the Reservation.Payments collection as necessary.

Taking a quick peek into the generated Customer class, you’ll find that the template also read the default value setting for CustomerID and applied it:

private int _customerTypeID = 1; 

Additional Guidance in Chapter 13

In the chapter from which this article is excerpted, you’ll also find guidance on creating a model that works with pre-existing classes and a nod to the upcoming “code first” feature, which is currently part of the Entity Framework Community Technical Preview (CTP).

Summary

In this article, you learned about one of the most important features added to Entity Framework in .NET 4: support for classes that do not inherit from the EntityObject class. You learned how to create simple classes that will still benefit from the Entity Framework’s modeling, querying, change tracking, and relationship management features. The ObjectContext can manage these classes by taking snapshots of their current state or by using proxy dynamic proxies to provide change notification and relationship management on the fly. You also got a sneak peek at Microsoft’s T4 template for creating POCO classes from the Entity Data Model.

Later chapters of Programming Entity Framework use POCO classes in application solutions, and demonstrate how they fit into more agile software architectures while benefiting from unit testing.

Listing 1: An ObjectContext class that works with the Contact and Address classes

class Entities : ObjectContext
{
  private ObjectSet&lt;Contact&gt; _contacts;
  private ObjectSet&lt;Address&gt; _addresses;

  public Entities()
    : base("name=POCOEntities", "POCOEntities")
  {
    ContextOptions.LazyLoadingEnabled = true;
    _contacts = CreateObjectSet&lt;Contact&gt;();
    _addresses = CreateObjectSet&lt;Address&gt;();
  }
  public ObjectSet&lt;Contact&gt; Contacts
  {
    get
    {
      return _contacts;
    }
  }
  public ObjectSet&lt;Address&gt; Addresses
  {
    get
    {
      return _addresses;
    }
  }
}

Listing 2: A class generated from an entity using the default POCO T4 template

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;

namespace BAGA
{
  public partial class Payment
  {
    #region Primitive Properties
    public virtual int PaymentId
    { get; set; }

    public virtual Nullable&lt;System.DateTime&gt; PaymentDate
    { get; set; }

    public virtual int ReservationId
    {
      get { return _reservationId; }
      set
      {
        if (_reservationID != value)
        {
          if (Reservation != null &amp;&amp;
                Reservation.ReservationId != value)
          {
            Reservation = null;
          }
          _reservationId = value;
        }
      }
    }
    private int _reservationId;

    public virtual Nullable&lt;decimal&gt; Amount
    { get; set; }

    public virtual System.DateTime ModifiedDate
    { get; set; }

    public virtual byte[] RowVersion
    { get; set; }

    #endregion

    #region Navigation Properties
    public virtual Reservation Reservation
    {
      get { return _reservation; }
      set
      {
        if (!ReferenceEquals(_reservation, value))
        {
          var previousValue = _reservation;
          _reservation = value;
          FixupReservation(previousValue);
        }
      }
    }
    private Reservation _reservation;
    #endregion

    #region Association Fixup
    private void FixupReservation(Reservation previousValue)
    {
      if (previousValue != null &amp;&amp;
            previousValue.Payments.Contains(this))
      {
        previousValue.Payments.Remove(this);
      }

      if (Reservation != null)
      {
        if (!Reservation.Payments.Contains(this))
        {
          Reservation.Payments.Add(this);
        }
        if (ReservationID != Reservation.ReservationId)
        {
          ReservationID = Reservation.ReservationId;
        }
      }
    }
    #endregion
  }
}