Partager via


Feature CTP Walkthrough: POCO Templates for the Entity Framework

The following post refers to an old version of the POCO Template. You can find information about the POCO Template for Visual Studio 2010 RTM here

Creating a Database using Model First

1 - Open the POCOWalkthru project

This project is a Console Application that has two files, "Program.cs"
and "Blogging.edmx". The "Blogging.edmx" is a Model First Entity Framework Model file for a blogging application. If you open the "Blogging.edmx" this is what you will see:

blog1

2 - Create an empty Database

In visual studio click the "View" menu and select "Server Explorer", which will show something like this:

blog1

In "Server Explorer" right click on "Data Connections" and select "Create New SQL Server Database…". The following dialog will appear:

blog1

Set "Server name" to ".\SQLEXPRESS" to target your local SQL Server Express installation, and enter "Blogging" for the new database name and click OK.

3 - Generate the Database Definition Language script (DDL) for the Blogging Model

Right click on the "Blogging.edmx" canvas and select "Generate Database Script from Model..." from the context menu:

blog1

This will bring up this screen:

blog1

4 - Create and Select a connection to your empty "Blogging" database:

On this screen you create or choose a new connection to your "Blogging" database.

If option is enabled select "No, exclude sensitive data from the connection string. I will set it in my application Code" .

Then click the "Next" button which will produce DDL for the "Blogging.edmx" and display that on this screen:

blog1

5 - Add the DDL file to your project

Click "Finish" and a new file will be added to your project called "Blogging.edmx.sql":

blog1

The contents of the file will look something like this:

blog1

 

6 - Execute the DDL using OSQL (or SQL Server Management Studio if you have it installed):

Open a Command Prompt in your "POCOWalkthru" project directory, where the "Blogging.edmx.sql" is located, and execute the following command:

OSQL -E -S ".\SQLEXPRESS" -i Blogging.edmx.sql

This command will add the necessary tables and Foreign Key relationships to your new "Blogging" database.

Convert the Project to use POCO Classes

7 - Add New Artifact Generation Item

Right click on the "Blogging.edmx" canvas and select "Add New Artifact Generation Item..."

blog1

8 - Select the POCO Template:

This will bring up the Artifact Selection Screen where you can choose which Template you wish to use.

blog1

On this screen select "EntityFramework POCO Code Generator" and rename your template "Blogging.tt" and click "Add".

9 - Dismiss the Security Warning:

A Security Warning will appear:

blog1

The template comes from a trusted source (Microsoft) so click "OK".

Your project will now look like this:

blog1

Understanding how the POCO Templates work

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.

When you choose the POCO Template two T4 templates files are added to your project. In this case one is called "Blogging.Context.tt" and the other is called "Blogging.Types.tt". If you wish to modify the generated code you simply modify one or both of these templates.

The "Blogging.Types.tt" file is responsible for generating a file for each EntityType and ComplexType in the "Blogging.edmx" model.

It also generates a file called "Blogging.Types.cs", which contains a FixupCollection class used by the POCO classes to keep the opposite ends of a relationships in sync. For example in the model we’ve been using to date when you set a Comment's Author to a particular person the FixupCollection class insures sure that the Person's Comments collection contains the Comment too.

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

Note that each time you edit any T4 template the dependent files are regenerated, so you shouldn’t edit the dependent files directly, or your changes will be lost.

Why two templates?

The primary goal of the POCO template is to produce Persistence Ignorant Entities classes.

However the strong typed ObjectContext derives from ObjectContext which is an Entity Framework class. So this template must live in a project with a reference to the Entity Framework.

By splitting the template into two, one part that generates the Entities and ComplexTypes 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 that has no persistence aware code in it at all.

The next few steps show how to do this.

11 – Create a new Class Library project in the solution called Entities:

blog1

12 – In the POCOWalkthru project add a reference to the Entities Project:

blog1

 

13 – Move the "Blogging.Types.tt" file into the Entities project

14 – Edit the "Blogging.Types.tt" to fix the link back to the Model

Since we have moved the template the relative location of the Model has changed, and we need to fix the template so its link back to the model is correct again. To do this you modify this line in the template from:

string inputFile = @ “Blogging.edmx” ;

To:

string inputFile = @ “..\POCOWalkthru\Blogging.edmx”;

This is simply a relative path from the template’s new location to the Blogging.edmx file in the other project.

Once you’ve done this Save the template, this will regenerate the POCO entity classes, so in solution explorer your solution should now look like this:

blog1

Notice the Entities project has no reference to the System.Data.Entity (aka the Entity Framework), and is completely persistence ignorant.

15 – Edit the "Blogging.Context.tt" file to use the “Entities” namespace

The classes in the Entities project are now in the " Entities " namespace rather than the " POCOWalkthru " namespace, so we need to modify the template that produces the string strongly typed context so that the generated class uses the " Entities " namespace or the class won’t compile.

blog1

 

Sanity Testing

16 - Add and Query for data in the Blogging Database

Now that we are producing POCO classes it is time to verify that we can add some data to the database and get it back again using our POCO classes and the Entity Framework.

Add this using to the program.cs file:

using Entities;

Then modify the Main() method by adding this code:

 using (BloggingContainer ctx = new BloggingContainer())
{
    Person person = new Person();
    person.EmailAddress = "billg@microsoft.com";|
    person.Firstname = "Bill";
    person.Surname = "Gates";
    ctx.People.AddObject(person);
    ctx.SaveChanges();
    Person query = ctx.People.First();
    Console.WriteLine("Saved and Found {0}", query.Firstname);
}

17 - Compile the project and run and you should see this:

blog1

Modifying the POCO Templates:

To modify how the POCO entities behave you can either add a partial class to extend the class produced by the template or you can modify the templates themselves. Indeed this is the whole point of this template based solution.

Modifying the T4 Template files is pretty simple, but it is beyond the scope of this basic walk through. You can expect us to release some customization examples soon.

Creating your own templates:

T4 provides a mechanism by which you can write common utilities that you share across templates, in something called include files.

The POCO template ships with a very useful include file that can be found in the installation directory here:

%INSTALLDIR%\Includes\EF.Utilities.ctp.CSD.ttinclude

This include provides a number of utility feature that make writing T4 templates easier, including:

  • Multiple output file support. By default each TT file produces just one output file, this multiple file support makes it possible to
  • Functions to produce Safe Identifiers. It is possible in the EDM to have identifiers, like an EntityType name, that are reserved in the target CLR language.
  • Functions to control the visibility (public / protected etc) of properties etc.
  • Functions to interact with the Entity Framework metadata
  • etc

Known Limitations in this version of the POCO Template

The first version of the POCO Template that works with .NET 4.0 Beta 1 has one major known limitation:
The POCO template generates Entities that don’t support change notification proxies.

Reasoning: There is a known bug in Beta1 of the .NET 4.0 that causes problems if notification proxies are used in conjunction with entity classes that do their own fix-up. Since the classes generated by the POCO template do their own fix-up, via the FixupCollection, customers using this template would immediately run into this bug if the generated entities that also supported change notification proxies. To support change notification proxies every property in the entity class must be virtual, so to avoid this we consciously generated non-virtual properties. The next release of the template for Beta2 will generate virtual properties again.

- Alex James
  Program Manager, Entity Framework

POCOWalkthru.zip

Comments

  • Anonymous
    June 23, 2009
    PingBack from http://www.alvinashcraft.com/2009/06/23/dew-drop-june-23-2009/

  • Anonymous
    July 04, 2009
    Will FixupCollections be included into .net 4.0 System.Collections namespace ?

  • Anonymous
    July 14, 2009
    For example in the model we’ve been using to date when you set a Comment's Author to a particular person the FixupCollection class insures sure that the Person's Comments collection contains the Comment too. well my english is not weak by any stretch of imagination but I am having hard time to diggest this! :) back to reading ;)

  • Anonymous
    July 14, 2009
    another question, if I get it right... the edmx file contains the domain model "picture", so where can I specify how my DB Schema will look like? The only thing I can see is the generated *.sql file but once generated it is already to late, so how to alter EF mapping behaviours aka conventions? I've read code only approach where this thing is "solved" but it lacks designer and is full of limitation, please enlighten EF newbie :) thanks

  • Anonymous
    September 13, 2009
    Am I missing something, but the POCO's generated are not serializable for use with WCF, i.e. virtuals and also the FixupCollection?

  • Anonymous
    November 02, 2009
    What exactly did the generator generate for your "POCO" object? Just wondering why the need for a generator for POCO objects. How would this work if the Person object had a list of Orders?

  • Anonymous
    November 08, 2009
    Why are none of the questions answered here ?

  • Anonymous
    November 08, 2009
    I have the latest VS 2010 and this menu option is not a part of my menu ?

  • Anonymous
    November 22, 2009
    In the POCOWalkthru-Final project, the BloggingContainer classe's constructors all set ContextOptions.DeferredLoadingEnabled = true; ObjectContextOptions class in .NET 4 doesn't have a DeferredLoadingEnabled property. It has a LazyLoadingEnabled property. Same thing, right???

  • Anonymous
    November 22, 2009
    Found my answer here: http://thedatafarm.com/blog/data-access/ef4-lazy-loading-on-by-default-but-what-about-pre-beta-2-models/ Renaming DeferredLoadingEnabled to LazyLoadingEnabled  is a breaking change from Beta 1 to Beta 2.

  • Anonymous
    November 25, 2009
    I've got CTP2 release of EF 4 which hasnt got this T4 template included. Where can I get the template from CTP 1 ? I can generate POCOs and adapt them as necessary.