Demystifying The Code

EF 4 – Implementing POCO Objects

The EF team has released the POCO template for use with VSTS 2010 Beta 2.  I thought I might examine POCO support in the new version of the Entity Framework without taking advantage of the template first, then get into the template in a later post.  This post will provide a simple end-to-end sample of implementing POCO objects in EF4 (Beta 2).  If you are reading this, you probably already know that POCO refers to “Plain Old CLR Objects”.  These are simple objects that are free of any framework dependencies.  POCO objects do not have to inherit from specific classes, do not have to implement specific interfaces, nor do they require any specific attributes.  They are simple, lightweight objects that are used to pass data around.

The Entity Framework 4 provides support for POCOs.  This post will illustrate this using a simple example from Northwind, a database that everyone has access to.  Feel free to follow along.  All you need is the following:

The SQL Data Model

image

Above you will see a small part of the SQL Data Model for Northwind.  These are the 2 tables that I am going to use.  In fact, for simplicity sake, I am not going to return each column from the 2 tables.  I have highlighted the columns that I plan on using.  With that out of the way, let’s get started:

 

Implementing this Simple Model without POCO

I will get started implementing this simple model without POCO.  Here goes:

  1. Open Visual Studio 2010 Beta 2
  2. Create a new Console Application
    • Click File > New > Project
    • Choose Console Application – For me it is under:  C# > Windows
    • Give It any name you want.  I’ll name mine SimplePOCO

    image

  3. Add the ADO/.NET Entity Data Model:
    • Click Add > New Item > ADO.NET Entity Data Model
    • Name It: NorthwindModel
      image
    • Click ‘Add’
    • Choose ‘Generate From Database’ and click ‘Next’
      image
    • Choose a connection to the Northwind database
      • (If you have not created a connection, you will need to click ‘New Connection’ and add a connection to Northwind.asdf
      • Save the entity connection settings in App.Config as ‘NorthwindContext’ 
        image 
      • Click Next
    • Choose the tables and set the Model Namespace
      • Choose the Customers and Orders Tables
      • Set the Model Namespace to NorthwindModel.  This is an important decision.  As you might infer, this will act as the namespace for your entire conceptual schema.  In other words, if you generate objects to represent your entities, they will have the NorthwindModel CLR namespace.  If you choose to create POCO objects, you will have to namespace them with NorthwindModel.
      • Click ‘Finish’
        image
  4. Delete the unneeded properties from our conceptual model. Remember that earlier I highlighted the columns in the database model that I wanted to use. We need to delete the properties from our conceptual model that map to the unneeded columns.
    • Simply single click on the unneeded columns (see image below) and click delete
    • You can multi-select columns

    image 

     

  5. Write some code in Program.cs to test the model:
    • Open Program.cs
    • Type the following code under Static Void Main

      static void Main(string[] args)
      {
          using (NorthwindContext nw = new NorthwindContext())
          {
              var query = from c in nw.Customers
                          where c.CompanyName.StartsWith("A")
                          select c;
      
              foreach (Customer c in query)
              {
                  Console.WriteLine("{0}", c.CompanyName);
      
                  foreach (Order order in c.Orders)
                  {
                      Console.WriteLine("\t{0}", order.OrderDate.ToString());
                  }
              }
      
              Console.ReadLine();
          }
      
      }

  6. Run It! You will see that not only does our model work, but we got lazy loading for free (I’ll get into Lazy Loading in another blog post.)

    image

That is it for implementing the model without POCO.  To illustrate that the object that were generated by the EF are not POCO, simply open the NorthwindModel.Designer.cs file.  This contains all of the designer-generated code.  

image

You need only take a brief look at the Customer or Order class to see that they have both EF attributes, as well as implement classes from the framework:

image

 

What Have We Got So Far?

Before I move on to the POCO side of things, I think it is probably best to describe a bit more about what has been done so far.  To start with, we used a wizard to generate an Entity Data Model (EDM) from our database schema.  If you are not familiar with what an EDM is, it contains a schema to the physical store (database), a schema for our conceptual model (how we want to see the data in our application) and a mapping between the two.  If you open the *.edmx file with an XML Editor (Right-Click NorthwindModel.edmx > Open With > XML Editor, you will see that, aside from the designer markup, the edmx is just that.

image

The second relevant thing that happened was that the designer generated some classes for us that map to the entities defined in the conceptual side of the EDM (using a template against the EDM).  You can see these classes if you open up the NorthwindModel.Designer.cs file.  These are the classes that will be used if you go through Object Services.  If you are not familiar with Object Services, you can think of it this way:  if you think of the Entity Framework as an ORM, Object Services provides the O.  In other words, if your query (LINQ to Entities or Entity SQL) returns objects, you are going through Object Services.  As seen in the step-by-step guide above, the classes are far from POCO.  There are multiple dependencies on the Entity Framework in the form of both attributes and inheritance.

 

Implementing the POCO Objects

In order to implement POCO Object, we first need to turn off the code generation that occurs by default.  Next, we create our POCO Objects.  Here are the steps:

  1. Set the Code Generation Strategy to "None"
    • Make sure the properties pane is visible
    • Click on whitespace in the edmx designer
    • In the properties window, set Code Generation Strategy to "None"

    image

  2. Add the Customer Class to the project
    • Right-Click the project > Add > Class
    • Name it Customer.cs
    • Change the namespace to NorthwindModel (Remember earlier that we set the model namespace to this)
    • Implement the Customer class so it looks like the following (excluding using statements)

      namespace NorthwindModel
      {
          public class Customer
          {
              public string CustomerID { get; set; }
              public string CompanyName { get; set; }
      
              List<Order> orders = new List<Order>();
      
              public List<Order> Orders
              {
                  get
                  {
                      return orders;
                  }
                  set
                  {
                      orders = value;
                  }
              }
          }
      }

  3. Add the Order Class to the project
    • Right-Click the project > Add > Class
    • Name it Order.cs
    • Change the namespace to NorthwindModel (Remember earlier that we set the model namespace to this)
    • Implement the Order class so it looks like the following (excluding using statements)

      namespace NorthwindModel
      {
          public class Order
          {
              public int OrderID { get; set; }
              public string CustomerID { get; set; }
              public DateTime OrderDate { get; set; }
      
              public Customer Customer { get; set; }
          }
      }

  4. We now need to add the context class. This is a class that inherits from ObjectContext and acts as the gateway or into your objects. You go through this context to access your entities as objects.
    • Right-Click the project > Add > Class
    • Name it NorthwindContext.cs
    • Change the namespace to NorthwindModel
    • Implement the NorthwindContext class so it looks like the following

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Data.Objects;
      
      namespace NorthwindModel
      {
          public class NorthwindContext : ObjectContext
          {
              public NorthwindContext() : base("name=NorthwindContext"){}
      
              public ObjectSet<Customer> Customers
              {
                  get
                  {
                      if (customers == null)
                      {
                          customers = base.CreateObjectSet<Customer>();   //"NorthwindContext.Customers");
                      }
                      return customers;
                  }
              }
      
              private ObjectSet<Customer> customers;
          }
      }

  5. Add a using statement to Program.cs for NorthwindModel:

    using NorthwindModel;

  6. Run It!

    image 

Summary

In this simple tutorial, we created an Entity Data Model, swapped out the objects that are generated by the designer for some custom POCOs that we created and wrote our own context object to expose our new object layer.  At the very end, our example worked, but we did not get some of the services that the designer-generated objects provided.  Most obviously, we did not get lazy loading.  I will put together a post for Monday that will illustrate how easy it is to implement that.  Oh yeah, and I’ll show off the new POCO template next week, as well.

Comments

One Response to “EF 4 – Implementing POCO Objects”

Trackbacks

Check out what others are saying about this post...
  1. [...] In my last post, I provided a simple end-to-end example where I used the Entity Framework designer to generate an Entity Data Model (EDM), I turned off the default code generation and implemented my own POCOs.  Everything worked fine, but at the end of the post I pointed out that I no longer had the Lazy Loading capability I had with the designer generated objects. [...]



Speak Your Mind

Tell us what you're thinking...
and oh, if you want a pic to show with your comment, go get a gravatar!

Demystifying The Code