Geeks With Blogs

News Dane%20Morgridge
Dane Morgridge Programmer, Geek, ASPInsider
A blog about code and data access

Persistence ignorance is, I believe, one of the most important features of an ORM tool and it is coming with Entity Framework 4 and Visual Studio 2010.  When your classes are persistence ignorant, they don't know anything about the data layer they are attached to and carry no dependency to said data layer.  Any application where your data will be passed between layers, like in a web service or web application, will greatly benefit from an ignorant set of data classes.  This was possible with Entity Framework 1, but you had to write your own custom classes and then also manage a translation layer to convert from Entity Framework classes to POCO (Plain Old CLR Object) classes.  While this does work, it requires additional code to be written that could be avoided.

Entity Framework 4 addresses this problem by allowing you to create a custom data context that interacts directly with the custom POCO objects.  Instead of needing a translation layer, the context can return your POCO objects in queries and also save those same objects, just like the standard context would with the normal Entity Framework objects.

To check out this new feature you will need Visual Studio 2010 beta 2 and the latest feature CTP.  The feature CTP contains a T4 template that will make working with POCO much easier.  If you want to work with POCO but don't download the CTP, you can still do so, but you will need to craft the POCO classes by hand instead of using the T4 template to do it for you.  I think the T4 template is a smoother way to do things so I would recommend getting the CTP.  Hopefully the T4 templates will be included with the final release of VS2010, I am assuming that they will be.

To get started, you need to have a data model with entities already in your project.  If you don't have a model already in your project, take a moment to check out my post on Model First Development. I will use the same database in this post so my model looks like this:

 EF4Poco_1
You can at this point write queries against the model like normal so the following code will compile and run with out issue:

   1: using (EFDemoEntities db = new EFDemoEntities())
   2: {
   3:     var people = db.Person.ToList();
   4: }


This is of course is using the base code generation template to use Entity Framework objects.  To start using POCO, we can change the code generation template by right clicking on the model and selecting "Add Code Generation Item":

image

This will open a dialog to add a new item.  Under "Installed Templates", you will need to select the "Code" section as the "Data" section is probably selected by default.  Once you see the following options, select the "EntityFramework POCO Code Generator"


 image

Now my solution has the following files:

image


The Model1.Context.tt and Model1.Types.tt files are the actual T4 templates used to generate the code. You can see that under the Model1.Context.tt there is a new data context class and under the Model1.Types.tt there are class files for all of your entities in your model. Also in the types is the Model1.Types.cs file.  This file contains some code to make the collections work better with the Entity Framework, but don't carry any dependency on the Entity Framework. 

If you build the project right now, you will very likely get 3 errors:

image 

All three of these errors are due to an error in the template surrounding the old option for deferred loading and the new option for lazy loading.  The template currently generates the context constructors as follows:

   1: public EFDemoEntities()
   2:     : base(ConnectionString, ContainerName)
   3: {
   4:     ContextOptions.DeferredLoadingEnabled = true;
   5: }
   6:  
   7: public EFDemoEntities(string connectionString)
   8:     : base(connectionString, ContainerName)
   9: {
  10:     ContextOptions.DeferredLoadingEnabled = true;
  11: }
  12:  
  13: public EFDemoEntities(EntityConnection connection)
  14:     : base(connection, ContainerName)
  15: {
  16:     ContextOptions.DeferredLoadingEnabled = true;
  17: }


The easiest way to fix this is to change the template.  Search the Model1.Context.tt file for DeferredLoadingEnabled = true and change it to LazyLoadingEnabled = true.  Saving the T4 template will re-generate the context file producing the following constructors:


   1: public EFDemoEntities()
   2:     : base(ConnectionString, ContainerName)
   3: {
   4:     ContextOptions.LazyLoadingEnabled = true;
   5: }
   6:  
   7: public EFDemoEntities(string connectionString)
   8:     : base(connectionString, ContainerName)
   9: {
  10:     ContextOptions.LazyLoadingEnabled = true;
  11: }
  12:  
  13: public EFDemoEntities(EntityConnection connection)
  14:     : base(connection, ContainerName)
  15: {
  16:     ContextOptions.LazyLoadingEnabled = true;
  17: }


The project will now compile without errors, including the data query.  The T4 template not only generates POCO objects but changes the entire code generation template so the original classes no longer exist.  This is helpful because you can start with the standard code generation and then change to POCO at a later date if you wish.  When using POCO and the template, you can still use all of the new features like lazy loading just as you can with the standard Entity Framework classes.

So as, you can see, switching your Entity Framework project to use POCO is very simple and doesn't require you to make any query changes to leverage it.  If you are not using persistent ignorant classes with Entity Framework, it's something you should take a serious look at.

Posted on Saturday, January 9, 2010 11:20 PM | Back to top

Copyright © Dane Morgridge | Powered by: GeeksWithBlogs.net