Persistence Ignorant POCOS part 2 - Entity Framework

Posted : Tuesday, 30 November 2010 08:58:42

This is the second post in a series comparing the developer experience of hooking up a POCO application to connect to an existing database schema using a selection of the more popular ORM tools. In this post I will first briefly describe the database schema and then go on to describe the process involved in hooking it up using version 4 of Microsoft's Entity Framework.

So the database schema is pretty simple and is shown below:

As you can see it consists of four tables and various foreign-key constraints. There is one table-per-class and the foreign-keys correspond to the relationships between the entities (see PART1) for a refresher. I aslo added a datetime column called insert_date to every table with a default value of getdate(). I generally do this whenever I'm building an application as I've found it invaluable when debugging various issues. Its not in any way essential to do this and these fields play no role in the application but they do serve to illustrate one of the 'features' of EF which I'll cover later. EF4 POCO does have support for lazy loading and change tracking but for the purposes of this post I'm not covering that functionality here.

Right then, on to the first example. After reading a few blog posts including the ADO.NET team blog. I added a new class library called LcaModel.EntityFramework project to the solution. I right-clicked (or left-clicked if you're a leftie ;-) the new project and selected add new item from the context menu. I selected a new ADO.NET Entity Data Model item from the list of available item types and entered the name EfLcaModel. I then chose the option to "Generate From Database". At this point I selected the option to create a new database connection and went through the wizard to create an Entity Framework connection string and store it in App.config (more on this later). I entered LcaModel and left all the other options in their default state. After completing the wizard two new files appear in the project one with a .edmx extension and beneath that is a .Designer.cs file. The next step in the process is to turn off code generation. To do this select a blank area of the designer surface and then in the properties window choose "None" as the Code Generation Strategy - incidentally if you double-click the corresponding Designer.cs file before doing this you will see a bunch of auto generated boiler-plate code which is the non-POCO EF data model. If you view the contents of this file after you change the Code Generation Strategy you will see all the auto-generated code disappears leaving only a comment with instructions on how to reenable code-generation.

So, this is where it starts to get a bit tricky. What you need to do, is open up the edmx file in an xml editor (do this by opening the context menu and choosing to open with "XML editor". There are four distinct sections to an edmx file. Its not a massive consolation but only three of these relate to the model itself. The bottom section is purely aesthetic and relates to the visual layout and is helpfully commented such. The exact nature of the edmx file is well beyond the scope of this post but there are three distinct sections. A storage section containing information about the database schema, a conceptual section related to the domain class model and a mapping section that maps the storage section to the conceptual section. In order to get EF to use my classes I had to go first go through the conceptual layer section and make sure all the class members used the names assigned in my domain model classes rather than the member names generated by the wizard. Next I had to go through the mapping layer section and make sure that the mapping between the storage layer and conceptual layer was also updated to use the correct property names.

During this process, Visual Studio will throw out a fair number of errors that aren't always the most informative. I found it a great help to take a copy of the original auto-generated mapping file prior to making any changes and refer back to it when I encountered such error messages that I couldn't fix.

So once I had the mapping file set up correctly I had to add a special class deriving from ObjectContext, this is the means by which EF communicates with the database (incidentally it is also this ObjectContext derived class that manages change tracking and lazy loading). I added a class to the project called LcaContext. For each EntitySet in the Conceptual layer section of the edmx file I added an ObjectSet<T> strongly typed on the relevant model class. An ObjectSet is a strongly typed collection of entities that provides the interface through which enties are retrieved and persisted to the database. The entire listing for this class is shown below:

    8     public class LcaContext : ObjectContext

    9     {

   10         public LcaContext(string connectionString)

   11             : base(connectionString)

   12         {

   13             Auctions = CreateObjectSet<Auction>();

   14             Items = CreateObjectSet<Item>();

   15             Bidders = CreateObjectSet<Bidder>();

   16             Bids = CreateObjectSet<Bid>();

   17         }


   19         public ObjectSet<Auction> Auctions { get; private set; }

   20         public ObjectSet&l

  • (This will not appear on the site)