Automapper and Silverlight 4? Yes Please!

I’m working on a fairly complex Silverlight application (Entity Framework 4, Prism/Unity, WCF RIA Services) and suddenly ran head-first into a need for some object mapping.  I haven’t done this before, but I had heard of Automapper so I Googled it and read the documentation.  Perfect!

Then I read up on the Silverlight Automapper release.  Uh-oh… last built in February 2010.  For Silverlight 3.  Curses…

I had two options at this point.  Do my mapping at the server side using the “regular” Automapper, or dig in and make Automapper Silverlight Edition work for me.  I downloaded the source, thinking I could (as I had done before with other projects) simply change the compilation target to Silverlight 4 and recompile.  Tried this and BAM!  No worky.  The version of mscorlib is 2.0.

Tried removing mscorlib and re-adding it from the Reference Assemblies.  BAM!  Visual Studio bug.

OK, so this will have to be a new project:

  1. File-New Project/New Silverlight Application.  Call it Automapper.Silverlight4.
  2. Copy the “lib” folder from the Automapper source into the root folder of your new build
  3. Add Reference to Castle.Core and Castle.DynamicProxy2 from the lib folder (don’t worry about the net3.5 folder, still works)
  4. Right-click the project and select Add Existing Item
  5. Navigate to the Automapper source and select all files in the root, then select Add As Link from the dropdown.
  6. Create Internal and Mappers folders and repeat the above steps for those folders in the Automapper source project.
  7. Delete links to DataReaderMapper and ListSourceMapper under Mappers folder (not supported by Silverlight.)
  8. Build!

It works!  I now have Automapper working in a Silverlight 4 application.  I’m sure I’m not the first to try this, but it’s good to know it’s possible.


How did you get started in programming?

I found this meme floating around some time ago, and thought it would be fun!

How old were you when you started programming?
Technically, about eight years old.  If you count plotting my initials on an Apple II+ in low-res, point by point, then that’s my first program.

How did you get started in programming?
My first real job programming was in the late 90′s.  I developed an event tracking system in Access for a single’s activity club.  They were a franchise until the franchiser packed up and disappeared, which left several franchisees around the country stuck with a bespoke Notes database.  The IT shop that developed the Notes system wanted more than the clubs could afford to support it.  I grabbed a book on Access and started coding.  A few months later, I had sold the system to five clubs.  I was hooked.


What was your first language?
Visual Basic was the first language I learned to any level of competence.  I’ve since moved on to C# and javascript.

What was the first real program you wrote?
The event and member tracking system was the first money-earning production program I wrote.

What languages have you used since you started programming?
C# is my “daily driver” language.  I also know Visual Basic, VBScript, and javascript.  I have a passing familiarity with C++ and Actionscript.

What was your first professional programming gig?
My first non-moonlighting gig was a contract with Texas Instruments, writing legacy ASP applications in VBScript.  I didn’t like that job very much, but it did demonstrate to me that I could make a living programming.

If you knew then what you know now, would you have started programming?
Absolutely.  I’m lucky to have found something I enjoy doing so much that also earns me and my family a living.  I’d still be doing it even if I couldn’t make a dime.

If there is one thing you learned along the way that you would tell new developers, what would it be?
99% of the information you need to learn your craft is available online.  I had a few mentors, but once I learned how to learn about programming, I discovered that the best answers are the ones you find for yourself.   That doesn’t mean you shouldn’t look to others for guidance and advice, just don’t use other people as your first resource for answers.  Don’t be satisfied with “it works.”  Challenge your assumptions, keep looking for the best patterns, and learn from the experts wherever you can.

What’s the most fun you’ve ever had … programming?
Ah, my magnum opus.  In the early aughts (2001) I developed an asset management system for a managed hosting company in Texas.  They were cramming their server data (over 7,000 servers) into a CRM and needed something better.  They were working on a hugely complex system, but it wasn’t due for months.  I bought several HP Jornada handheld computers- clamshell things with a full keyboard and PC card slot.  All the servers were marked with barcodes.  We scanned the ID information and “U-Top” (the position of the servers in the racks) of all 7,000+ servers in a single weekend, using the handhelds and some barcode scanners.  The data was then synched to a SQL Server using SQL Server CE 1.0.
Then, using legacy ASP and some amazing artwork created by a colleague, we built a rack visualizer.  I developed a web-based system that allowed users to view the datacenter in a top-down view, click a rack, and see the contents of any rack.  You could hover over a server and see its status, and over blank space to reserve  a spot for a new server.  This combined with a tracking system that allowed users to track the progress of a server from the build center to the data center and back, as well as movement of assets within the corporate office.  I learned a lot from this experience, and consider it my greatest overall achievement… so far :)


Bizarre Errors When Using Telerik Controls

I’m in the process of developing a complete line-of-business application in Silverlight.  I have a Telerik Premium license and most of the controls I use are Telerik controls.

At one point in my development process, I innocently added an “Up/Down” control to a UserControl, using Blend 4.  Suddenly and for no apparent reason, I could no longer see the UserControl in Visual Studio 2010.  I would get a very odd looking blank page.  I could still edit it in Blend, however, and I’m under a time crunch so I carried on.

Today, Blend started crashing when trying to open the UserControl.  I now had no design surface and I’m struggling with other issues.  Among other strange issues, this error appeared in the VS designer:

An unhandled exception was encountered while trying to render the current silverlight project on the design surface. To diagnose this failure, please try to run the project in a regular browser using the silverlight developer runtime.

If I reloaded the designer I would go back to the blank page.  After much gnashing of teeth, I tried copying this control to another project in my solution.   After commenting out a few lines, Voila!  Design surface!

The Solution: When I used Blend to add the “up/down” control, it added a reference to a prior version of the Telerik.Windows.Controls.Input assembly to my project.  I had several other Telerik assemblies referenced, all Q3 2010 version.  The mismatched versions played hell with the designer and I was stuck.  I removed the offending prior versions and replaced them with the correct ones, and life was good.  Hope this saves you some time and gray hairs.


My Journey with the StackExchange API

On May 23, Jeff Atwood posted an announcement to the StackOverflow blog.  The StackOverflow team was getting to work on version 1.0 of the StackExchange API.  As you know from my previous post, I’m something of a StackExchange fan.  Needless to say (though I’ll say it anyway) I was pumped (did that rhyme?)

Two months later, I’ve created three new open-source projects based on the StackExchange API:

StackLINQ: A LINQ Provider to the StackExchange API
StackedDeck:  The TweetDeck of StackExchange.  Watch questions from any and all StackExchange sites stream in by tag.
StackWatcher:   A system tray application that watches in real-time for changes in your rep, favorites, and badge awards, and notifies you with some popup toast.

This effort has been an intensive and interesting experience.  I learned a TON about LINQ and Windows Presentation Foundation, WPF being the basis for StackedDeck and StackWatcher.  I won’t lie and say I did it just for the fun of it. I would love to win cool stuff for my efforts, but that’s truly not the whole deal.

LINQ, WPF, and Silverlight are three of my favorite Microsoft technologies.  I’ve learned a lot more by writing the StackLINQ library and the WPF apps, and I’ll be blogging and demoing my experience over the next several months, starting with StackLINQ.  StackedDeck is now version 0.9 beta.  It will be getting a major refactoring as I refine it to take better advantage of binding and MVVM.  I will probably roll StackWatcher’s functionality into StackedDeck, and will definitely be updating StackedDeck when the StackExchange API v2 is released, so you can ask and answer questions too!

This process will be “televised”- that is, blogged and probably made into videos.  All three projects are on BitBucket for your perusal at the links above.  Enjoy, and watch this space to follow my progress.


How to Get Value From StackOverflow

I’ve been a regular user of StackOverflow since shortly after the beta.  It helped keep me sane during a period of semi-employment.  My company was bought out and I was paid to do nothing for eight months.  I know this sounds great, but it wasn’t.  Desperately bored and wanting to do something, I spent hours answering SO questions.

Over the course of eighteen months, I’ve learned a few useful ways to get the most out of this amazing site.  I thought now would be a good time to share the best ones.

There are four common ways to get value from StackOverflow:

  • Asking questions
  • Finding answers by landing on SO through a Google search
  • Finding answers by searching SO directly
  • Answering questions

We’ll take each one in turn.

Asking Questions

Asking questions on StackOverflow is a skill.  First and foremost, questions must be answerable. The progenitors and maintainers of the site (Jeff, Joel, and The Community) created StackOverflow to contain Questions and Answers, not Flames and Opinions. That’s not to say the latter doesn’t happen, but subjective questions are generally closed quickly.  I have only asked a few questions on SO when I’ve been truly stuck, and have been very satisfied with the results.  Answers to well-crafted questions come quickly.

Do:

  • Make questions concise and readable
  • Include enough information (code!!)
  • Markup code so it’s readable.  Use the ` before and after code blocks, or use the little binary button.
  • Include the steps you have already taken (no “How do I write Facebook?  Plz send the codez!”)
  • Accept Answers! Answerers do pay attention to your accept rate.

Don’t:

  • Ask a question until you understand the problem well enough to articulate it clearly
  • Ask for help with homework unless you have tried at least ten things (and include those things)
  • Ask subjective questions.  “Why” questions are often subjective.
  • Downvote just because you disagree with an opinion, or out of retribution.  No one will know you did it, but it’s baaad karma.

Finding Answers

Finding answers on SO is easy:  search Google.  Over half of my technical searches lead to SO.  Searching SO directly is useful too, but here’s a pro tip:  when you’re at your wit’s end and you start asking a question, pay attention to the questions that pop up as you enter your question title.  For some inexplicable reason, that search seems to come up with better results.  It may be that your direct SO searches should be phrased Jeopardy-style, in the form of a question.  I haven’t tried that yet.

Answering Questions

Here it is- the fun part.  Answering questions on SO is all about giving back to the community, helping your fellow programmer.  In a divine light of altruistic service, the Oracles of StackOverflow share their wisdom with the masses.

Oh, and there’s that Reputation thing too :)

Honestly, earning rep for helping people is fun.  Somehow the one without the other isn’t quite the same, regardless of the fact that the reputation has no intrinsic value whatsoever.*

So, good answers:

Do:

  • Read the Entire Question. Answers that do not take the entire question into account are often wrong and will get downvoted.
  • Use Markdown to your advantage.  Bold is great for one-liner summaries of your answer.  Italics are good for emphasis.  Use bulleted lists when appropriate.
  • Mark code appropriately, just as with questions.
  • Make the answer easy to read by inserting gaps between thoughts, even if they’re only one or two sentences.  Long paragraphs are hard to read.
  • Include enough detail to answer the question without being long-winded.
  • Focus on your area of expertise.  You shouldn’t have to research your answer except to fill in blanks.

Don’t:

  • Rush the answer.  Getting in first doesn’t automatically mean getting the highest-voted answer.  You can edit to add more detail later (but be careful not to write a novel, unless the question warrants a long answer)
  • Guess.  Back up your information with references.  I rarely ever post an answer without a link to supporting information.
  • Answer with just a link, unless that link is exactly what the poster needs.

In Summary

Those are my guiding principles as I use SO.  This is certainly an incomplete list, so please leave comments and I’ll update the post with the best ideas.

If you enjoy answering questions on any StackExchange site, check out StackWatcher.

*Actually, Telerik offers a free copy of their Premium Collection to answerers with over 10K reputation :)

Tagged, I’m It: My Reading List

So I received a tag from Sara Dutkiewicz yesterday, asking that I share my reading list.  I’m a huge fan of hard science fiction, and over the years I’ve read a lot of it.

I just finished Saturn’s Children by Charles Stross.  It was okay, not Stross’ best work.  If you want to read great Stross, pick up:

  • Singularity Sky
  • Iron Sunrise
  • Accelerando

Before that was The Unincorporated Man by Dani and Eytan Kollin.  This is an awesome book!  I think it would make a great movie.  In the hands of a good writer and director, it could be a classic.  The next book, The Unincorporated War, is out in hardcover.  I’ll wait until March for the paperback- $25 is too much for a book.

Here is an incomplete list of my other favorite authors:

Peter F. Hamilton:  Nights Dawn series, Nano Flower, Fallen Dragon

David Brin: Uplift War series, Kiln People

Greg Bear:  Eon, Forge of God

Timothy Zahn:  Cobra series, Thrawn Trilogy (first Star Wars books set after episode 6)

Neil Gaiman:  American Gods, Sandman, Anansi Boys

Stephenie Meyer:  The Host, Twilight series (yes, I read them…)

Kim Stanley Robinson:  Mars trilogy (one of my favorites), Years of Rice and Salt

Tad Williams:  Otherland series

Vernor Vinge: A Deepness in the Sky, A Fire Upon the Deep

Robert Heinlein: Stranger From a Strange Land, The Moon is a Harsh Mistress


Entity Framework 4: Then and Now

Contents

  • What is OR/M?
    • A Little History
    • The Impedance Mismatch
    • OR/M to the rescue
  • Entity Framework 1.0
    • Entity Data Models
    • Code Generation
    • Generated Classes
    • Entity Framework 1.0 FTW!…?
  • The Controversy
    • Persistence Ignorance
  • Entity Framework 4
    • New Features
    • Persistence Ignorance and POCO
    • T4 Templates
    • T4 Generated Files
    • Model-First Development
    • FK Associations
    • Code-Only Entities

What is Object Relational Mapping?

A Little History

Over ten years ago, I was working a contract developing legacy ASP websites with a SQL Server 6.5 backend (on stone tablets, in the driving snow, uphill both ways…)

Set oConn = Server.CreateObject("ADODB.Connection")  oConn.Open "DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=" & Server.MapPath("DB.mdb")
Set rsUsers = Server.CreateObject("ADODB.Recordset")
rsUsers.Open("SELECT UserID FROM Users";, oConn,1,3)

--SQL CREATE PROCEDURE usp_GetCustomers () AS
...

Anyone who did this ADO development in VB6 or ASP probably noticed a trend:  at least 50% of your code was database-related.   Then you got to stop what you were doing writing code, move over to Query Analyzer, and write scads of stored procedures.   Bummer.

Then, in 2001, we got .NET.  Whoohoo!

//C#
SqlDataAdapter da = new SqlDataAdapter(“usp_GetCustomer;", myConnection);
da.TableMappings.Add("Customers1", "Orders");
DataSet ds = new DataSet();
da.Fill(ds, "Customers");

--SQL  CREATE PROCEDURE usp_GetCustomers ()  AS
...

OK, so it’s strongly typed.  Great… but wait a minute.  The story hasn’t really changed here.  I’m still writing tons of Connections, Commands, and Parameters.  I’m still spending half my life (and my budget) hacking together repetitive SQL scripts.  Things got incrementally better with the Enterprise Library and Data Access Application Block, but the fundamental problem remained.

What is the problem?  The Impedance Mismatch.

“Impedance Mismatch” the clever term used to describe the fact that the Data/Persistence tier of n-tier applications was just not connecting cleanly to “upper” tiers.  Part of the reason for this was, as I’ve said, we had to work in two different languages to get anything done.  This code mismatch increased the amount of code we had to write, increased development costs, and was just no fun.

The other part of the impedance mismatch is the Modeling Mismatch. Relational databases are great for storing and retrieving data, but relational schemas don’t always make good Entity Relationship Models.  We needed too much code contortionism to get the relational, two-dimensional, tabular database return formats to return data in a useful, hierarchical, entity-relational manner.

Object Relational Mapping to the rescue!

About five years ago, some smart folks (I’m looking at you, Ayende, Rob Conery, and Frans Bouma) decided they’d had enough.  They said,

I should be able to get my data by writing my queries in C#, VB.NET, or IronPython, for Pete’s sake.  I should not have to write another line of SQL.  I should be able to represent and query against Entities that contain data in the shape I need it without regard the database schema.

Thus was born NHibernate, Subsonic, and LLBLGenPro.  These OR/M projects were among the first to be introduced to the .NET platform.  Through a variety of approaches, these projects:

  • Provided the ability to abstract the database schema to a set of objects (aka Entities) whose shape did not have to match 1:1 with the tables in the database.
  • Allowed developers to write queries in the .NET language of their choice by cross-compiling queries written in C#/VB.NET directly to dynamic SQL.

Not to be left out, Microsoft joined the party in 2008.  Entity Framework 1.0 was introduced with Visual Studio 2008 SP1.  In the box was:

  • System.Data.Entity
  • A new designer for editing Entity Data Models
  • LINQ to Entities
    Let’s take a quick look at Entity Framework 1.0 before we dive into EF 4.

Entity Framework 1.0

The center of the story for EF 1.0 is the Entity Data Model.

edmAn Entity Data Model (EDM) is an XML-formatted file with an .edmx extension.  EDMs contain three sections: the Storage Model, Conceptual Model, and Mapping Model.

  • The Storage model is simply an XML representation of a database schema.
  • The Conceptual model is the representation of the Entities in the EDM.
  • The Mapping Model is the map between columns in the database tables and properties of the Entities.

The Entities in an EDM may contain data fields from a single table (Table per Type) or could be packed together in a single table (Table per Hierarchy.)  It’s also possible to split an Entity between tables.  EDMs in Entity Framework 1.0 are created as Table per Type Entities by default, which means there is one Entity per table.  It’s possible to get crazy with other mapping strategies, but it requires manually editing the .edmx file, which isn’t fun.

Code Generation

Creating the EDM with the designer is just one half of the excitement- the other half is the magic worked behind the scenes by the EntityModelCodeGenerator. This is a class in the Entity Framework that is used by Visual Studio to parse the .edmx file, and generates classes that reflect the shape of all the Entities in an EDM.  It uses internal logic and CodeDOM voodoo, but more on that later.

Generated Classes

If you pop open the “codebehind” of a standard EF 1.0 EDM file, you’ll see an autogenerated file containing one class: the Context.

public partial class AdventureWorksProdEntities : ObjectContext
   {
       #region Constructors
       /// <summary>
       /// Initializes a new AdventureWorksProdEntities object using the connection string found in the 'AdventureWorksProdEntities' section of the application configuration file.
       /// </summary>
       public AdventureWorksProdEntities() : base("name=AdventureWorksProdEntities", "AdventureWorksProdEntities")
       {
           this.ContextOptions.LazyLoadingEnabled = true;
           OnContextCreated();
       }

The Context is your gateway into the Entities in the EDM.  It has a few constructor overloads for accepting various connection strings or objects (the EntityConnection object.)  Then, for each Entity, a special type of property:

[global::System.CodeDom.Compiler.GeneratedCode("System.Data.Entity.Design.EntityClassGenerator", "4.0.0.0")]
        public global::System.Data.Objects.ObjectQuery<Product> Products
        {
            get
            {
                if ((this._Products== null))
                {
                    this._Products= base.CreateQuery<Product>("[Product]");
                }
                return this._Product;
            }
        }

These are not collection properties.  They are query properties that derive from ObjectQuery.  The Entity Framework relies on some new coolness in the System.Expressions namespace to manipulate expression trees. Expression trees allow you to represent code statements as objects.  Once you can do that, you can translate those trees into something new, like SQL.

Using an Entity Data Model to do all the old CRUD is super-simple:

using (AdventureWorksProdEntities ctx = new AdventureWorksProdEntities())
{

      var products = from p in ctx.Products
                              select p;

}

We now have a query ready to go.  Nothing has hit the database yet.  To do that, we:

products.ToList();

Now the query represented by expression in the LINQ statement above gets reworked by the LINQ to Entities Provider and sent to the database.  Voila, we have a populated collection!  We can get fancier:

using (AdventureWorksProdEntities ctx = new AdventureWorksProdEntities())
{
    var products = ctx.Products.Include(“ProductSubCategory”).Select(x => x).ToList();

}

This is called eager loading.  The Include() extension method tells the Entity Framework to go ahead and get all the ProductSubCategory Entities and populate them as properties of the Product.  The “ProductSubCategory” string refers to a Navigation Property of Product.  Navigation Properties represent the relationships between Entities.

If the Include() call were not there, this would throw an exception:

int id = products.First().ProductSubCategory.Id;

That code would throw a NullReferenceException because none of the ProductSubCategory entities are loaded.  If we don’t use Include(), we have to do this to avoid the exception:

products.First().ProductSubCategory.Load();

That line explicitly loads the ProductSubCategory related to the first Product in the list.

Making and persisting changes to Entities in EF 1.0 requires just a few lines of code:

using (AdventureWorksProdEntities ctx = new AdventureWorksProdEntities())
{
     //Assigning a different ProductSubCategory
     Product p = products.First();
     ProductSubCategory psc = ctx.ProductSubCategory.First();
     p.ProductSubCategory = psc;
     ctx.SaveChanges();
}

How many lines would this take without an OR/M?  Commands, connections, parameter objects, and all those SQL stored procedures would probably run to over 100 lines, easily.

Entity Framework 1.0 FTW! Right?

So, as we’ve seen, Entity Framework 1.0 is a big step forward.  What could be better?

A lot, actually.

Consider the code above.  Let’s assume the the code above reassigns one Product’s related ProductSubCategory properties to a different one that is already in the database.  We have to query for the new one and assign it to the Product, then call SaveChanges() on the Context.  Suppose we already know that the ID for the ProductSubCategory we want to assign is 16.  Why not just set the value directly and be done?  Entity Framework 1.0 just doesn’t do foreign key references that easily.

Difficult foreign key references, “black-box” code generation, and the limited choice between eager and explicit loading were just a few of the perceived quirks of EF 1.0.

The Controversy

In fact, Entity Framework 1.0 turned out to be quite controversial among the OR/M cognoscenti.  There were several features that many considered critical to a good OR/M that EF 1.0 just didn’t have.  Concern ran so high amongst these developers, that Microsoft might impose (by their estimation) a substandard platform on an unsuspecting community, that the Entity Framework Vote of No Confidence was drafted and posted online.  Over 800 developers, many of them Microsoft MVPs, signed on.  It appeared that Microsoft had work to do.

To be sure, the Vote of No Confidence reads like a doctoral dissertation.  It’s great for insomnia.  However, it did raise several legitimate points.  I won’t recapitulate the entire thing here, but I will call out the issue that is probably most important.

Persistence Ignorance

What the bleep is Persistence Ignorance?  I’m going to use a real-world example to explain.

Suppose your boss comes to you and says “You, I need you to create a console app that will go to the web, read the page at the URL in the first argument, find some keywords, and save them to a file.  It will be used internally.  We’re not selling this thing, but we’ll probably need to add to it, so make sure it’s designed well enough.”

OK, no problem.  File-New Project, Console app.  Add reference- System.Web…

Bothered yet?  You should be.  I’m about to add a static reference to System.Web in my console app. Bad foo.  I’m violating a few important things here, like Single Responsibility Principle and Separation of Concerns.  What should I be doing?  I should add a new class project, right?  Right.  My business logic belongs in its own assembly.  That assembly should get the reference to System.Web.

Entity Framework 1.0 had a similar problem.  Peep this:

public partial class Product: EntityObject
{
}

This tiny little excerpt from the Context class of an EF 1.0 Entity Data Model exposes a major issue with EF 1.0.  All the Entity classes generated by an EF 1.0 EDM derive from EntityObject.  This means that my Entities are tightly, statically coupled to their persistence implementation.

Boo.

Enterprise Architectures and Service-Oriented Architectures consider this type of coupling to be an antipattern.  Entities are really just Data Transfer Objects (DTOs.)  Good architectural design dictates that DTOs must not have any knowledge of (i.e. direct coupling to) their persistence implementation(s).  They must be Persistence Ignorant.

Suppose your boss came back to you two weeks after your keyword-finding app was out in the wild, used by your colleagues every day:

Great job!  Now we need it feed directly into an Oracle database, a SQL database, a MySQL database, and post out to a WCF Service.

Now we see where Persistence Ignorance offers a huge benefit.  If your app tier is bound directly to the persistence layer, you now get to rewrite, refactor, and retest.  If, however, you had based the persistence operations on some interfaces, you can write each persistence implementation separately, test them, and plug them in with a Dependency Injection framework like Ninject or Spring.NET.  Done.

By many accounts, Entity Framework 4 goes a long way to address the concerns voiced in the Entity Framework Vote of No Confidence.  There is certainly disagreement as to whether the new features go far enough, but it’s safe to say that no one can reasonably claim Microsoft wasn’t listening.  So, without further ado:

Entity Framework 4

The new features of Entity Framework 4 include:

  • New Features
    • Persistence Ignorance
    • POCO (Plain Old CLR Object)
    • T4 Code Generation
    • Self-Tracking Entities
    • Model-First Development
    • FK Associations
    • Code-only

    Let’s dig in.

Persistence Ignorance and POCO

POCO objects, or “Plain-Old CLR Objects” are objects with no dependencies outside the basics, like System and System.Collections.  Here’s an example:

    using System;
    using System.Collections;
    using System.Collections.Generic;

    public class Person
    {
    public int Id {get; set;}
    public string FirstName {get; set;}
    public string LastName {get; set;}
    List<Product> Purchases {get; set;}

    }

There’s no data-layer baggage here, just a few simple properties and a collection property of the Products this Person bought.

Entity Framework 4 will not only allow us to use a simple class like this, it will help us make one:

edmcontextmenu

The context menu on the right comes up when you right-click whitespace in an EDM.  The new Code Generation Item option raises this dialog:

codegenerationdialog

We have three options listed:

  • ADO.NET EntityObject Generator
  • ADO.NET POCO Entity Generator
  • ADO.NET Self-Tracking Entity Generator

These three options will generate classes for us to support our interaction with an EDM, but the mechanism is very different from what it was in EF 1.0.

T4 Templates:  The Coolest VS2010 Feature You Never Heard About

Instead of the EntityModelCodeGenerator, Entity Framework 4 uses T4 Templates.  T4 stands for Text Template Transformation Toolkit. This is an incredibly powerful feature of VS2010 that you get for free. T4 is used in ASP.NET MVC, Entity Framework, and other project types, and is the new preferred way to do code generation.  Details on T4 templates are way out of scope here, but I strongly recommend you look into them.  They’re the unsung hero of VS2010.

The important point about T4 templates is that they are just text files, so you can make them your own.  You can modify the ones that come with VS2010, or write new ones from scratch.  This puts you in complete control of the code generation process for Entity classes, or any other type of text-based file, for that matter.

The three options in the dialog above are T4 templates.  The EntityObject Generator creates classes in the same style as EF 1.0, with entities deriving from EntityObject.  The POCO Entity Generator and Self-Tracking Entity Generator is where things get interesting and new.

T4 Generated Files

If you select ADO.NET POCO Entity Generator from the list of available templates, you’ll see this in Solution Explorer:

pocofiles

Note: To get the EDM to generate using T4 templates instead of the EntityModelCodeGenerator, you must right-click the .edmx file in Solution Explorer, select Properties and clear the “Custom Tool” setting in the Properties pane.

The files with the .tt extension are the templates.  The POCO generator has two: one for the Context, which does have to keep a reference to the Entity Framework, and another that generates a separate class file for each Entity, plus an additional class that defines FixupCollection<T>.  FixupCollection<T> is used as the basis for one-to-many relationship properties, such as between Customers and Orders.  The FixupCollection<T> base class ensures that modifications to one side of a relationship stay in synch with the other end.  For example, if you delete an Order, the Customers’ Orders collection is updated as well.

Here’s a look inside the generated Context:

    public partial class AdvWorksHREntities : ObjectContext
    {
    public const string ConnectionString = “name=AdvWorksHREntities”;
    public const string ContainerName = “AdvWorksHREntities”;
    #region Constructors
    public AdvWorksHREntities()
    : base(ConnectionString, ContainerName)
    {
    this.ContextOptions.LazyLoadingEnabled = true;
    }
    public AdvWorksHREntities(string connectionString)
    : base(connectionString, ContainerName)
    {
    this.ContextOptions.LazyLoadingEnabled = true;
    }
    public AdvWorksHREntities(EntityConnection connection)
    : base(connection, ContainerName)
    {
    this.ContextOptions.LazyLoadingEnabled = true;
    }
    #endregion
    #region ObjectSet Properties
    public ObjectSet<Department> Departments
    {
    get { return _departments  ?? (_departments = CreateObjectSet<Department>(“Departments”)); }
    }
    private ObjectSet<Department> _departments;
    public ObjectSet<Employee> Employees
    {
    get { return _employees  ?? (_employees = CreateObjectSet<Employee>(“Employees”)); }
    }

    …

This Context looks similar to one generated by EF 1.0, with a few key differences.  Firstly, this context class contains only constructors and Entity query properties, but not the definition for the Entity classes themselves.  Separating these classes into their own files allows the Entity classes to live in an assembly that has no binding to System.Data.Entity.

Another key difference is that these query properties derive from ObjectSet instead of ObjectQuery.  ObjectSet derives from ObjectQuery, but also implements IObjectSet.  IObjectSet contains methods that were previously implemented by the EF 1.0 context object, such as AddObject and DeleteObject.  The upside of having these methods implemented as part of an interface is testability and composability:

  • You can mock out the methods of the interface and test the Entity classes without having to hit a database.
  • You can use the interfaces to glue together your persistence and business logic layers with a DI framework like Unity or Spring.NET.

Now let’s peek inside an Entity class:

public partial class Employee
{
#region Primitive Properties
public virtual int EmployeeID
{
get;
set;
}
public virtual string NationalIDNumber
{
get;
set;
}
public virtual int ContactID
{
get;
set;
}

…

#region Navigation Properties
public virtual ICollection<EmployeeAddress> EmployeeAddresses
{
get
{
if (_employeeAddresses == null)
{
var newCollection = new FixupCollection<EmployeeAddress>();
newCollection.CollectionChanged += FixupEmployeeAddresses;
_employeeAddresses = newCollection;
}
return _employeeAddresses;
}
set
{
if (!ReferenceEquals(_employeeAddresses, value))
{
var previousValue = _employeeAddresses as FixupCollection<EmployeeAddress>;
if (previousValue != null)
{
previousValue.CollectionChanged -= FixupEmployeeAddresses;
}
_employeeAddresses = value;
var newValue = value as FixupCollection<EmployeeAddress>;
if (newValue != null)
{
newValue.CollectionChanged += FixupEmployeeAddresses;
}
}
}
}
private ICollection<EmployeeAddress> _employeeAddresses;

Here we have some simple, primitive properties like EmployeeID.  We also see the definitions for the associative Navigation Properties, implemented as ICollections.  The getters and setters of these Navigation Properties include the association fixup logic.  FixupCollection<T> actually derives from ObservableCollection<T>, which has events that fire when the members of the collection change.  This is used in the POCO classes to fixup both ends of related Entities when objects are added or removed from one end or the other.

Convention Over Configuration

So how does the Entity Data Model magically “know” how to handle POCO classes?  There’s no magic, just convention.  Entity Framework expects POCO classes to follow conventions, such as the ones for property names.  The property names of your POCO classes must match exactly to the names defined in the EDM.  If the conventions are followed to the letter, the CRUD “just works.”

Lazy Loading

Now is a good time to talk about Lazy Loading.  Remember our earlier example of eager loading:

    using (AdventureWorksProdEntities ctx = new AdventureWorksProdEntities())
    {
    var products = ctx.Products.Include(“ProductSubCategory”).Select(x => x).ToList();
    }

This query retrieves all Products and their related ProductSubCategory in a single query.  EF 4 introduces the ability to load related Entities “on demand”:

    using (AdventureWorksProdEntities ctx = new AdventureWorksProdEntities())
    {
    var products = ctx.Products.ToList();
    int id = products.First().ProductSubCategory.Id;
    }

Without lazy loading, the code above would throw a NullReferenceException because the ProductSubCategory was neither pulled in with Include(), nor loaded explicitly with Load().  EF 4 allows the code above to “automatically” query for the related ProductSubCategory if it is not already loaded.  Lazy loading is “on” by default.  Here is one of the constructors in a generated POCO context class:

public AdvWorksHREntities()
: base(ConnectionString, ContainerName)
{
this.ContextOptions.LazyLoadingEnabled = true;
}

This and all other constructors in a POCO context class has the LazyLoadingEnabled ContextOption set to true.  Accessing a related entity will automatically send a query to the database to retrieve the entity.

There’s a caveat here.  Take a gander:

    using (AdventureWorksProdEntities ctx = new AdventureWorksProdEntities())
    {
    var products = ctx.Products.ToList();
    foreach (Product p in products)
    {
    Console.WriteLine(p.ProductSubCategory.Id.ToString());
    }
    }

This is a case where lazy loading can get you into trouble.  Suppose there were 100 Products in the products List<Product>.  The code above would result in 100 additional queries, one for each Product in the list.  This can get even worse in the case of one-to-many relationships.  The point to remember is that you must be very conscious in your use of lazy loading.  It can be very handy if used carefully, but it’s easy to abuse it.  This can have negative consequences for your application performance.  This is true for any OR/M, of course, but it can catch a developer upgrading from EF 1.0 unawares.

Self-Tracking Entities

We’ve seen how Entity Framework 4 is better suited to Enterprise and Service-Oriented architectures due to POCO and Persistence Ignorance.  Entity Framework 4 introduces another improvement with Self-Tracking Entities.

Service-Oriented architectures rely on serialization to move objects across service boundaries.  If we want to send an EF 1.0 Entity across a WCF service, it must be Detached from its Context using the Detach() method.  If that Entity is modified and returned back to the service layer to be persisted, it must be attached to a Context using Attach().  Unfortunately, it doesn’t end there.  The state of the Entity must be checked and the ApplyPropertyChanges() method must also be used to synchronize the modified Entity with the existing Entity in the database.  SaveChanges() can then be used to update the database.  This all amounts to a very manual, tedious process.

The Self-Tracking Entity (STE) template offers an improvement to this process by including extension methods, classes, and interfaces that track an Entity’s state after it is transmitted over a service.  There is a catch however: self-tracking entities only work over WCF, and only if the destination client is running .NET 4.  This is due to the fact that the classes and interfaces that support the tracking must be available at the destination as well as the source.  So, STEs are useful in homogenous (.NET) environments but they don’t support heterogeneous environments where the destination service based on a platform other than .NET.

Model-First Development

If you’ve used EF 1.0, you’ve seen this dialog:

newedm

There hasn’t been much use for the “Empty model” until now.  EF 4 supports designing the model first, then using that model along with POCO classes.  It also supports database generation.  If you create your EDM, add Entities to it, then right-click on an empty area of the design surface:

dbgeneration

Select “Generate Database from Model” and you’ll get a SQL script that will generate all the tables required by your EDM.

FK Associations

One of the big headaches with EF 1.0 was foreign key references.  Remember our code sample:

using (AdventureWorksProdEntities ctx = new AdventureWorksProdEntities())
{
//Assigning a different ProductSubCategory
Product p = products.First();
ProductSubCategory psc = ctx.ProductSubCategory.First();
p.ProductSubCategory = psc;
ctx.SaveChanges();
}

All we’re doing here is reassigning the ProductSubCategory of a Product.  We should be able to do that just by setting the ID of the new ProductSubCategory foreign-key value on the Product, right?  Not so in EF 1.0.  As we see above, we actually have to go get an instance of the one we want to reassign to by querying.

This is no longer necessary in EF 4.

fkassociation

If you leave “Include foreign key columns in the model” checked, the foreign-key IDs become primitive properties of your entities, available for reassignment without hassle.  These properties are called “FK Associations” and brings zen back to the process of reassigning entity relationships.  EF 1.0 Associations are still included and are referred to as “Independent Associations”.

Code-only Entities

The Code-Only option is currently available only in CTP.  The CTP includes the assembly Microsoft.Data.Entity.CTP, which provides classes that support a “zero-model” method for representing Entities.  The ADO.NET team has provided a great walk-through that takes you through the process of setting up a sample project.

Code-only development is similar in style to NHibernate and other OR/M tools that focus on code-based implementations. The idea behind “code-only” or “code-first” is that the Entity Model is expressed exclusively in code, with no .edmx file in the middle.  POCO classes represent the Entities.  Relationships and other facets are coded using EntityConfiguration<T>.  Once your object model is designed, the ContextBuilder<T> can use your Context class to generate a database for your model.  ContextBuilder<T> and EntityConfiguration<T> provide complete control over the mapping model used to generate the tables.  The Entity classes can be separated from the EF-dependent classes in true POCO style.

Summary

The major new features of EF 4 include:

  • Persistence Ignorance
  • POCO support
  • T4 Code Generation
  • Model-First Development
  • FK Associations
  • Code-Only Development

The debate rages on as to whether Entity Framework 4  matches its competitors.  It does seem safe to say that EF 4 is ready for prime-time, and deserves evaluation alongside alternatives such as NHibernate and LLBLGenPro.  I’ve been using EF 1.0 since it was released and I can personally say that the improvements in EF 4 save time and promote better architecture over the previous version.

References

POCO in the Entity Framework: Part 1 – The Experience:
http://blogs.msdn.com/b/adonet/archive/2009/05/21/poco-in-the-entity-framework-part-1-the-experience.aspx

What’s New and Cool in Entity Framework 4.0:
http://www.develop.com/entityframework4

Model First with the Entity Framework 4:
http://blogs.msdn.com/b/adonet/archive/2009/11/05/model-first-with-the-entity-framework-4.aspx

Transparent Lazy Loading for Entity Framework – part 1:
http://blogs.msdn.com/b/jkowalski/archive/2008/05/12/transparent-lazy-loading-for-entity-framework-part-1.aspx

Attaching/Detaching Entities in EF 1.0:

http://community.dynamics.com/blogs/cesardalatorre/comments/9584.asp


Follow

Get every new post delivered to your Inbox.