It’s a Love/Hate Relationship

I’ve been using Entity Framework for quite some time now.  I’ve built enough enterprise-level software to know what type of real-world limitations exist.  So I’m going to talk about what I love about Entity Framework that other ORMs don’t do, then I’m going to talk about the problems with EF that I hate.  I’ll be talking specifically about EF-6, version 6.0.2.

What I love about EF-6

First, and foremost is the visual interface.  It’s very easy to use and you can setup a complex ORM in seconds.  Just create a new edmx file (by right-clicking on the project and selecting Add -> New Item -> Data -> ADO.NET Entity Data Model), select your data server and database, then select tables/stored procedures, and save.  The visual tool shows relational integrity constraints and it rolls up many-to-many relationships to reduce clutter.  The visual interface feature is a big bonus.

The update model from database feature is nice.  That’s the feature that Linq-to-SQL lacks.  That is the number one reason our team switched from Linq-to-SQL to EF, because it was a nightmare adding or changing a field in a table.

I like the fact that all the T4 script files and their accompanying auto-generated cs files are folded up under the edmx file.  This makes the project neat and tidy looking and it keeps new programmers from poking around in source files they don’t need to mess with.  This is a technique that is commonly used in some of the best Graphical User Interfaces: Show the basic tools, hide the complex.

What I hate about EF-6

Now it’s time to get into the ugly side of EF-6.  It seems that EF-6 was designed from the ground up with no knowledge of Linq-to-SQL.  I’m sure the designer(s) behind EF have used Linq-to-SQL, but maybe they have never used an ORM in a real-world application.  Because the shortcomings that I’ve run into are obvious and right in your face.

First, there’s the problem of only one database connection per context (or edmx file).  This is a huge issue since you can’t join tables across databases.  I’ve stumbled across a couple articles that talk about hacking around this, but there should not be any hacking required.  I could possibly live without this feature and not get too up in arms if it wasn’t for the next flaw that I’m going to talk about.

The second issue, and it really ranks at the top with the first issue: EF ignores name space conventions.  This is a problem because I can’t just create a small context containing just the tables I need for a class in my project.  I would prefer to have the ability to create a sub-directory in a project containing a class cs file and an edmx file all related to each other in functionality.  This would keep the scope of the problem limited to that sub-directory.  I discovered early on that this does not work with EF.  Once I drag the same table into two different edmx files, it gets ugly.

The next problem which is made worse by the fact that I can’t get around it because of problem two involves the size of the edmx file.  As this file grows, my queries take longer at start up time. That’s because all the xml is contained in one large monolithic file that must be loaded by EF first.  This file contains all the xml definitions of the tables that were included in the edmx file, plus all the mapping information that is shown when using the visual interface.  If I were a designer working for Microsoft, I would have broken each table into it’s own xml file and kept the visual stuff in its own file.  Then EF could have loaded only the xml data that it needed for the tables being joined in the query.

The last problem I’m going to mention involves the xml file and the fact that this is computer generated.  Computer generated files are difficult to merge when using version control.  Even under TFS (Team Foundation Server) this is a mess when more than one person is modifying the edmx file and attempting to check in their changes.  Again, separation of the visual attributes from the table definitions could have reduced this problem.

Other issues with ORMs

There are other issues with EF, but these issues are found in Linq-to-SQL and I’m betting they exist in NHibernate (though I can’t speak to NHibernate much since I don’t have any real-world experience, yet).  

Probably the biggest thorn in my side about ORMs is the lack of unit test mocking ability.  My issue is that there should be an entire mocking class built right into the ORM itself, or an add-on mock class that imitates what the ORM does using in-memory tables.  EF comes close and I like a lot of the mocking capabilities of EF.  Unfortunately, EF can’t mock certain things that annoy me like crazy.  One issue involves the use of the SqlFunctions.StringConvert() method.  This method cannot be mocked.  There are some work arounds on the internet, but they’re not pretty.  Another not-mockable “feature” of ORMs is the stored procedure.  This I can understand, since the stored procedure is dependent on the database itself and not the ORM.  But wouldn’t it be cool….

Summary

So you’re probably wondering why I’m whining about all this.  I’m putting this information out there so future developers can weigh the issues “before” they start building an enterprise level application.  My project is at the point where it will be difficult and expensive to switch ORMs.  So now, I have to do a lot of research on another product and weigh the cost of “switching the ORM” with what we will gain as we move forward.  

So here are the attributes that must be achieved in order for an ORM to pass the enterprise-level acceptance test:

1. It must be fast, even with a large number of tables with complex integrity constraints.

2. It must be built on a solid foundation.  Adding a field to one table should not cause hours worth of rework because of auto-generated code problems.

3. It must play nice with source control.  All of the productivity gains I get from the ORM are worthless if my development team is spending more time trying to re-merge their changes.

4. It must be unit testable.  In today’s development environment, unit testing is required.  It’s no longer an option.  ORM developers need to design with unit test-ability in mind.

If you are building a project that contains only one database with 20 or 30 tables, then EF will do you good.  In most other circumstances, I would warn you off of Entity Framework for now.  Maybe version 7 will fix some of the issues I’ve listed.  In the back of my mind, I’m wondering how EF made it to version 6 with all these flaws (OK, Microsoft skipped over versions 2 and 3, but it’s still a lot of versions to get through without fixing these issues).

 

Leave a Reply