Entity Framework: Friend or Foe?

For the majority of my professional life, my time has been spent in the CMS world with a product called Ektron.  In this platform, data access is done through something called the Framework API.  It is pretty intuitive and makes data access pretty easy.  It’s also Ektron’s way of keeping developers from mucking with the database directly and hosing the application (which is surprisingly easy to do). So when I decided to break away from Ektron and start building freestanding .NET applications, the term ORM was completely foreign to me.  Not only are there plenty of ORM’s to choose from to build your application (EF, Subsonic, Massive, Dapper, Petapoco, etc), but each has it’s own Pros & Cons, and each is like it’s own little programming language.  Needless to say I got overwhelmed pretty quickly, but with anything, the only way to learn it is to dive in and start doing.

So when our next project rolled around, the timing was perfectly aligned with the new release of Entity Framework 5.  My team evaluated the feature set and decided to roll with it, and use Code First.  Below is a quick data dump of my experience with it.

Pros:

  1. Great for prototyping and getting started quickly.
    One of super critical parts to building a greenfield application is getting the persistence layer (database) correct early (or as close to correct as you can).  Most developers out there are not DBA’s (nor want to be) and know enough to work with the data they get from the database proficiently but architecting a database is another thing altogether.  Entity Framework’s Code First is perfect for these developers because it allows the developer to write the code in an object oriented way and the database is created based on your C# classes in the background.
  2. Auto Migrations
    During prototyping I want to waste as little time as possible on the persistence layer and just want to focus on the application and business logic to get the app running and demo-able as quickly as possible.  The reason for this is as you are building your app, requirements change, you run into problems you didn’t foresee, etc.  Having to re-design the database when these things happen just adds more time to the project.  Prior to using Entity Framework I used mock repositories to give me fake data to work with.  Then when the persistence layer was serviceable after the prototyping phase, I would add in the code to connect the app to real data in the database.  Auto-migrations takes the pain of setting up and modifying your database away because as your models (POCO’s) change in your code the database changes with it.  This frees you up to just concentrate on code.
  3. Simplifies data access down to 3 or 4 lines of code.None of this junk anymore:
    string query = "SELECT OrderID, CustomerID FROM dbo.Orders;";
    
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        SqlCommand command = new SqlCommand(query, connection);
    
        connection.Open();
    
        SqlDataReader reader = command.ExecuteReader();
    
        while (reader.Read())
        {
            //do work here
        }
    
        reader.Close();
    }
    

    Now it’s just:

    using (var db = new DbContext()) 
    {
        tableName.ToList().ForEach(o =>
        {
            //do work here
        });
    }
  4. Ability to export Migration C# or VB code to Raw SQL if you have a DBA.
    If you prefer to not use Auto-Migrations, you can explicitly create C# or VB migration files that have the ability to be exported to raw SQL and given to a DBA for review.

Cons:

  1. Sometimes EF makes things more complicated than they should be.
    There were times where I have resorted to using raw sql commands, instead of Entity Framework’s preferred syntax due to time constraints of a project because EF was just a time vacuum:

    using (var db = new DbContext())
    {
        db.Database.ExecuteSqlCommand("INSERT INTO table (column1, column2) 
                                       VALUES (1, 2)");
        db.SaveChanges();
    }
  2. .Attatch() is flaky
    .Attatch() is a way to attach objects to a db context that are obtained from a source other than a query.  For example, passing a UserProfile object in to a data access method via a parameter.  There’s no reason to query the database for a UserProfile object when I already have it.  This type of behavior can have huge performance ramifications on your application.However, it never seemed to work right when a complex object graph (with 1 or more EF navigation properties) is involved. So many times I to resort to what I explained above, querying the database to get the object I already had to please EF before I could call an update or insert.
  3. EF starts to dictate shape of the domain model.
    As our project got more complex I noticed that we had to alter the shape of our POCO’s just to please EF.  Data Annotations, Navigation properties, Naming Conventions, etc.  I like having clean POCO’s that are not tied to any type of ORM technology.  The Fluent API is a way around this, but that had problems of it’s own.  There’s only so much time you can spend “learning” on a project before you just have to GET IT DONE!
  4. Speed.
    Up until the latest version (EF5), EF was the slowest ORM out there.  EF5 claims 67% performace boost from Microsoft but until you run tests with your own app and hardware, you’ll never know if that’s true.  Our app using EF5 is not lightning fast but it’s not a dog either.  If you write your app with a clean 
    separation of concerns from the data access layer you can always swap out the ORM at a later date if EF is the cause of your app’s latency.  Not the sexiest work to do but…
  5. One to one mappings were not straightforward.
    We had all kinds of problems with referential integrity and multiplicity errors and such when setting up one to one mappings.  Good article on EF and one to one mappings. 
  6. In code first there is no stored procedure support but it is coming in EF6.
    http://entityframework.codeplex.com/wikipage?title=Roadmap

This list just details my likes/dislikes with using EF5 for the first time.  Our app was not overly complex so we didn’t dive right into the deep end of the pool and take advantage of the more advanced features of Entity Framework but I learned a lot.  I was amazed at times and severely disappointed at times but over all our experience with EF5 was a good one and I’m looking forward to EF6, which should be right around the corner.

Get started with EF here!