Chris Umbel

POCO Entities in ADO.NET 4.0

One of the most anticipated features of the Entity Framework 4.0 is the ability to have POCO (Plain Old CLR Object) entities. This allows developers to produce domain objects free of any persistence baggage, with no requirements imposed inheritance-wise. Up till now entity objects were required to either inherit EntityObject or had to implement IEntityWithKey, IEntityWithChangeTracker and IEntityWithRelationships.

This makes it far easier to use EF with legacy domain classes and keeps data models clean and unconcerned with their own persistence.

To demonstrate this feature I'll start out with a basic SQL Server table structure and test data that maps employees to departments.

Database

create table Departments (
  Department_ID int identity primary key clustered,
  Name varchar(255) not null
)

create table Employees (
  Employee_ID int identity primary key clustered,
  FirstName varchar(255) not null,
  LastName varchar(255) not null,
  Department_ID int references Departments
)

Then I'll fill them up with some test data.

insert into Departments 
select 'Information Technology'
union
select 'Accounting'

insert into Employees
select 'John', 'Doe', 1
union
select 'Bill', 'Barley', 1
union
select 'Jane', 'Doe', 2
union
select 'Lynn', 'Smith', 2

Entity Model

Now I'll generate an entity model named StaffModel from the database just as I would traditionally. The difference is that afterward I'll remove "EntityModelCodeGenerator" from the entity model's "Custom Tool" property (see section highlighted in green in the image to the right).

Domain Classes

With the entities complete I'll define some basic domain classes to persist. Note that there's no configuration required to map class names to tables and property names to columns. The framework relies purely on naming convention to accomplish the mapping.

public class Department
/* look ma, no subclassing EntityObject*/
{
  public string Name { get; set; }
  public int Department_ID { get; set; }
  public List<Employee> Employees { get; set; }
}

public class Employee
{
/* look ma, no subclassing EntityObject*/
  public int Employee_ID { get; set; }
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public Department Department { get; set; }
}

Object Context

Now I'll write a context that will connect my domain objects to their storage. This is really the only plumbing I'll code by hand.

public class StaffContext : ObjectContext
{
  private ObjectSet<Employee> _employees;
  private ObjectSet<Department> _departments;

  public StaffContext()
    : base("name=StaffEntities", "StaffEntities")  
  {
    _employees = CreateObjectSet<Employee>();
    _departments = CreateObjectSet<Department>();
  }

  public ObjectSet<Employee> Employees
  {
    get 
    { 
      return _employees; 
    }
  }

  public ObjectSet<Department> Departments
  {
    get
    {
      return _departments;
    }
  }
}

Usage

With the EF end of things complete I'll whip up a simple console app to query the model.

class Program
{
  static void Main(string[] args)
  {
    // establish connection
    using (StaffContext context = new StaffContext())
    {
      // query database
      var departments = context.Departments.Include("Employees");

      foreach (Department department in departments)
      {
        Console.WriteLine(department.Name);

        foreach (Employee employee in department.Employees)
        {
          Console.WriteLine(string.Format("\t{0}, {1}", 
            employee.LastName, employee.FirstName));
        }
      }
    }
  }
}

Which produces the following output:

Information Technology
        Barley, Bill
        Doe, John
Accounting
        Doe, Jane
        Smith, Lynn

Conclusion

The inclusion of POCO entities in EF 4 solves several common complaints amongst ADO.NET developers. They assist in separating concerns, easing testability and simplifying integration with existing domain classes.

In my estimation this could spur adoption of EF which has been received somewhat coldly thus far.

Thu Jul 30 2009 16:07:49 GMT+0000 (UTC)

Follow Chris
RSS Feed
Twitter
Facebook
CodePlex
github
LinkedIn
Google