It is now recommended to use the DbContext template described in this blog post. It will generate simpler POCO entities and a context class derived from DbContext which provides a simpler API.
The POCO Template can be used to generate persistence ignorant entity types from an Entity Data Model. The goal of this walkthrough is to demonstrate a basic scenario of its use with Entity Framework.
- Any edition of Visual Studio 2010 post-Beta 2.
- Entity Framework POCO Template for C#, available here.
- A local SQL Server 2008 Express instance has to be installed as SQLEXPRESS. Otherwise, it might be necessary to make changes to the connection string in the configuration file or to regenerate the database from the included SQL script.
- Download and extract the initial solution attached to this post.
Note: While the following walkthrough uses C#, all the concepts described here apply to the Visual Basic version of the template which is available here.
1. Setting up the project
The solution includes a project named POCOTemplateWalkthrough that is a Console Application. To facilitate us focusing on how to use the POCO Template, the solution already contains the following files:
- Blogging.edmx: a simple Entity Data Model for a blogging application.
- Blogging.mdf: a SQL Server database for the blogging model.
- Blogging.edmx.sql: SQL Server script that can be used to regenerate the database if needed.
- Program.cs: the initial Program class created for console applications.
- App.Config: an application configuration file containing the connection string for the blogging database.
Normally, when you start a new project using Entity Framework you can import a model from an existing database. In version 4.0, you can now create a database starting from the model. To learn more about the Model-First feature, see this blog post.
2. Understanding the Blogging model
If you open the “Blogging.edmx” file, this is what you will see:
Five simple classes are used to model a blogging application: Blog represents an actual blog. A Person can act as the owner of a blog, but also as the author of a Post or a Comment, which both inherit from the abstract class Entry. A Blog can have multiple Posts, and in turn, each Post can have several Comments.
Notice that we are using foreign key associations in this model: Blog has both Owner and OwnerID properties. It is important to note, however, that exposing foreign key in entities is not a requisite for Entity Framework or the POCO Template.
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, expand the Blogging.edmx associated files by clicking on the arrowhead close to it, and then open the file Blogging.Designer.cs:
POCO stands for 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.
3. Adding the POCO template
One of the advantages of POCO entities is that they are simple. So in general, it is very easy to write them by hand. However, when you have an Entity Data Model as the starting point and want your entity classes to be POCO, the POCO Template can provide a good jumpstart by generating POCO classes that correspond to the model instead of the default EntityObject classes.
In order to do this, you can right-click on an empty area of the “Blogging.edmx” canvas and select “Add Code Generation Item…”
This will bring up the Add New Item dialog, in which you can choose which Template you wish to use. The POCO Template can normally be found under the Visual C# Items or the Visual Basic Items category.
On this screen select “ADO.NET POCO Entity Generator” and type “Blogging.tt” as the name of the new item. Then click on the “Add” button.
Note: A Security Warning dialog will appear each time a T4 generates code from a template in your machine:
Normally, T4 template files generate code when they are added to a project or when they are saved. If you have downloaded and installed the template form a trusted source, you can click “OK”.
4. Understanding how the POCO Template works
Once you have added the POCO template, your project will look like this:
When you choose the POCO Template two T4 template files are added to your project. In this case one is called “Blogging.Context.tt” and the other is called “Blogging.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 “Blogging.tt” file is responsible for generating a file for each EntityType and ComplexType in the “Blogging.edmx” model. For instance, the POCO version of the Blog class looks like this:
“Blogging.tt” also generates a file called “Blogging.cs”, which contains a FixupCollection<T> 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 when you set a Comment’s Author to a particular person the FixupCollection<T> class ensures that the Person’s Comments collection will contain 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 and save any T4 template the dependent files are regenerated, so you shouldn’t edit the generated files directly, or your changes will be lost. If you wish to modify the generated code, you can modify one or both of these templates.
Note: Why two templates?
The primary goal of the POCO template is to produce persistence ignorant entity classes.
However, the strongly 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 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 that has no persistence aware code in it at all.
The next few steps show how to do this.
5. Moving entity types to a separate project
To continue, add a new Class Library project to the solution called Entities.
You can remove the class1.cs file created by default in the new project.
Now, in the POCOTemplateWalkthrough project, add a project reference to the Entities Project:
Next, move the “Blogging.tt” file into the Entities project. To do that, you can simply drag & drop the file into the Entities project in the Solution Explorer window, while you hold the Shift key at the same time.
6. Edit “Blogging.tt” to fix the link to “blogging.edmx”
The POCO Template T4 template files need to be able to read metadata from the EDM model in order to generate the right code. Since we have moved the template, the relative location of the Model has changed, therefore we need to fix the template so its link back to the model is correct again. To do this you can modify a line close to the top of the template from from:
string inputFile = @ “Blogging.edmx” ;
string inputFile = @ “..\POCOTemplateWalkthrough\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, and this will regenerate the POCO entity classes. You can check that the contents of the file “Blogging.cs” under “Blogging.tt” has the right contents to verify that the path entered above is correct:
Also, notice the Entities project has no reference to the System.Data.Entity (aka the Entity Framework), and is completely persistence ignorant.
7. Change “Blogging.Context.tt” namespaces to match “Entities”
The classes in the Entities project are now in the “Entities” namespace rather than the “POCOTemplateWalkthrough” namespace, so you need to modify the namespace used by the context template. Otherwise the compiler won’t find the entity types and the solution won’t compile. You can do this by setting the value of the “Custom Tool Namespace” property to “Entities” in the property browser of the template item.
Once you do this, save the template file again (i.e. by pressing Ctrl+S) and you should be able to compile the solution without errors.
8. Sanity check: adding and querying for data in the Blogging database
Now that we are done 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.
First, add this using statement at the top of the “Program.cs” file:
Then modify the Main() method by adding the following two blocks of code:
9. Final step: compile and run the code
After following all the steps described before, you should be able to compile and run the code and see the following screen:
Customizing classes and templates
The entity type, complex type and ObjectContext classes generated by the POCO Template are all partial classes. Therefore, it is often possible to extend the behavior of entities by just adding a partial class containing additional code to the project.
In other cases it might be better to modify the templates themselves to generate different code. Indeed, the whole point of a template-based solution is that you can decide the behavior you want only once, and then obtain the desired output from different models by applying a modified template.
Modifying the T4 Template files consists of modifying a text file, but it is beyond the scope of this basic walkthrough. Customization of T4 templates for entity code generation is described in this post.
Creating your own T4 template is not covered in this walkthrough either. You can expect future posts to explore more in depth this area. In the meanwhile, it is worth mentioning that T4 provides a mechanism by which you can write common utilities that you share across templates, in something called include files. The POCO template uses an include file called EF.Utility.CS.ttinclude. This include provides a number of utility feature that make writing T4 templates for Entity Framework easier, among others:
- Multiple output file support. By default each TT file produces just one output file, this multiple file support makes it possible to create a single class per file, which has several advantages.
- Functions to produce Safe Identifiers. It is possible in the EDM to have identifiers, like an Entity Type 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
Known issues in this version
- The POCO Template does not work with ASP.NET WebSite projects: A bug in multiple output file support prevents the POCO Template from working on WebSite projects. A fix will be available in a future update. In the meanwhile, you can place the template in a separate class library project and add a reference to the class library from the WebSite.
- Running a query with Include and MergeOption equal to NoTracking may cause an exception: There is a problem in the interaction between the implementation of relationships fixup code in classes generated by the POCO template and the change tracking POCO Proxies enabled by the POCO Template. We are currently investigating this issue.
- Detach can cause nullable foreign keys properties to be nulled: The implementation of relationship fixup cannot distinguish the reason an entity is being removed from an object graph. When Detach is applied to an entity that is related to others through foreign key associations, fixup logic will react to references being nulled and elements being removed form collections and will set the corresponding FK properties to null. We are currently investigating this issue.
- The AssociationChanged event can be raised twice: The AssociationChanged event is raised twice with CollectionChangeAction.Add when fixup occurs in the model such that a collection is modified. We are currently investigating this issue.
- The fixup logic will load all related entities if Lazy Loading is enabled. The template keeps relationships consistent even if the related objects haven’t been loaded in the context. You would need to disable Lazy Loading when using the POCO template to avoid this.