-->

06/12/2011

Entity Framework 4.0 - POCO


In earlier Post we have seen how to create a entity data model file and how to use Entity Framework infrastructure in our class library.
Lets have a close look at both File structure and Properties Window.

If you observe the highlighted items, the "Code Generated Strategy" property is set to Default. This means the entity generation from .edmx file will be taken care by framework itself. Thus resulting in .Designer.cs file which was highlighted in right.

By default, a model created with the Entity Data Model Designer produces entity classes based on System.Data.Objects.DataClasses.EntityObject, which provides basic services to entities, such as change notification, identity and relationship management. Special attributes are used to decorate classes and properties, so that Entity Framework can at runtime relate each class and property with the corresponding property in the model. In order to see the kind of code that is generated by default, open EntityMVCDB.Designer.cs file.

So these classes are tightly coupled to the default services provided and persistence aware. This can be a big time problem in real world scenario.
All we need is Persistence Independent , Simple and Independent classes.
In this scenario POCO is the resolution we should opt for. POCO is not a tool name, its an approach.

POCO - Plain Old CLR Objects
POCO support in Entity Framework 4.0 means that these EntityObject-based types can be replaced with much simpler classes. POCO entity types are not required to inherit from any particular class and do not need attributes to map to the homologous elements in the model. Instead, types and properties in the objects and in the model are associated at runtime simply based on their names.

We don't need to do any Hand written job to create simple entities from the .edmx file. There are numerous tools for this. The one i sued and we gonna discuss is "ADO.NET C# POCO Entity Generator".

Lets see step by step how to implement Entity Framework with better flexibility using POCO.

Step 1: Download "ADO.NET C# POCO Entity Generator" from here.

Step 2: Install the Entity Generator. While installing make sure it is integrating with VS2010.
Step 3: Once you installed, restart VS2010. Open the old solution which we have used for earlier example.
Open .edmx file. Right click on the entity explorer and select "Add Code Generation item".
Step 4: A wizard will be opened displaying the different Code generation techniques available on your machine. We choose POCO.
Why not other 2 options available?  They are the default options provided by EF , but they still generate single context files thus having tight coupling with Database and dependent entities.

Step 5: When you choose the POCO Template two T4 template files are added to your project. In this case one is called “POCOEntities.Context.tt” and the other is called “POCOEntities.tt”. T4 stands for "Text Template Transformation Toolkit", and is a template engine that ships with Visual Studio. The Entity Framework POCO Template leverages T4 to allow you to customize code generation.
The “POCOEntities.tt” file is responsible for generating a file for each EntityType and ComplexType in the “EntityMVCDB.edmx” model.
POCEntities.cs an additional class file will be generated with POCOEntities.tt. This class will be taking care of run time binding of different Foreign keys. Means, if Class A has a property of type Class B, both the classes will be generated individually with simple property names. But the association will be achieved in run time using this single class file.

The second template (“POCOEntities.Context.tt”) produces a strongly typed ObjectContext for the “EntityMVCDB.edmx” model. You use this strongly typed ObjectContext to interact with your database.

By splitting the template into two, one part that generates the Entity Types and Complex Types and one that generates a strongly typed context, it makes it possible not only to have Entities and ComplexType that are persistence ignorant but further to put those classes in an assembly / project (DAL) that has no persistence aware code in it at all.

Step 6: Now two thing we need to observe are
a. Default designer class file of .edmx file.
b. Property window of .edmx explorer.
You should observe "Code Generation Strategy" property is set to None and the default designer file is saying, now generation of code is not my task and its been taken care by some thing else.

Step 7: Finally lets have a look at the class file generated in POCOEntities.tt template.
//------------------------------------------------------------------------------
// 
//     This code was generated from a template.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// 
//------------------------------------------------------------------------------

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

namespace EntityConnector
{
    public partial class Category
    {
        #region Primitive Properties
    
        public virtual int CategoryID
        {
            get;
            set;
        }
    
        public virtual string CategoryDesc
        {
            get;
            set;
        }

        #endregion
        #region Navigation Properties
    
        public virtual ICollection Products
        {
            get
            {
                if (_products == null)
                {
                    var newCollection = new FixupCollection();
                    newCollection.CollectionChanged += FixupProducts;
                    _products = newCollection;
                }
                return _products;
            }
            set
            {
                if (!ReferenceEquals(_products, value))
                {
                    var previousValue = _products as FixupCollection;
                    if (previousValue != null)
                    {
                        previousValue.CollectionChanged -= FixupProducts;
                    }
                    _products = value;
                    var newValue = value as FixupCollection;
                    if (newValue != null)
                    {
                        newValue.CollectionChanged += FixupProducts;
                    }
                }
            }
        }
        private ICollection _products;

        #endregion
        #region Association Fixup
    
        private void FixupProducts(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.NewItems != null)
            {
                foreach (Product item in e.NewItems)
                {
                    item.Category = this;
                }
            }
    
            if (e.OldItems != null)
            {
                foreach (Product item in e.OldItems)
                {
                    if (ReferenceEquals(item.Category, this))
                    {
                        item.Category = null;
                    }
                }
            }
        }

        #endregion
    }
}

If you observe care fully, its a straight simple entity with the supporting fixup functionality. Its persistence independent, and loosely coupled to Database context. Thus you can move these entities entirely to a separate layer (DAL).

Thus we covered the basics of Entity Framework with POCO in this post.
We will cover some interesting topics about how to
    a. segregate 2 POCO templates into different layers of application
    b. how we gonna use this infrastructure for a successful and a reliable communication with database
    c. How to use Model Map for better way of writing code.

Is it helpful for you? Kindly let me know your comments / Questions.

4 comments:

  1. Its great post with much clarity

    ReplyDelete
  2. Certainly Yes... Great job Pratap Pilaka....
    Shivakumar Kampilla :)

    ReplyDelete
  3. Hi,

    Of late, I have been trying my hands on the Entity framework with ASP.Net MVC 4. I have some basic understanding of Entity framework and its differernt approaches such as Database first, Model first and Code first. What my understanding is that the Code first approach is the newest of the other two and is a preferred approach over the other two.

    I have created a sample ASP.Net MVC 4 application in which I have a Model class for Contact. A Contact is an entity in my application. It's a pretty simple application that I am building which will allow a user to manage contacts.

    So basically, a Contact has several attributes such as Id, Name, Phone, Email. What I have done is that I have created two separate classes for Phone and Email.

    In the main Contact class that has Id and Name as its attribute, I have declared Phone and Email as List objects like this. public IList phones; and similarly for email also.

    Now, these two (Phone and Email) are basically a collection properties in the Contact class (which contains properties for Id and Name).

    I am stuck here and not able to move forward. I don't think there is any issue with my design. However, facing a challenge while using these POCO objects with entity framework 6.1.

    Wondering if I can share the code with you on email or if I can get in touch with you on IM to understand and resolve the issue. Pls let me know what's the best way to connect.

    Thanks!

    ReplyDelete
  4. Extremely Well Explained :)

    ReplyDelete