Wednesday, July 18, 2012

The problem with ORMs

pigdogOver the last 8 years I’ve done a lot of thinking and experimenting with different persistence models. If you’d asked me 6 years ago what a persistence layer should look like I would have whole heartedly suggested an ORM like nHibernate.  Linq to SQL came along and initially looked promising but I quickly soured on it in favor of Entity Framework.  Then I actually tried to use Entity Framework in a production app and quickly found that in spite of the initial query writing efficiencies, it caused problems in other areas and the net result was that it didn’t save me any time at all but did add limitations and complexity to my app. 

So what was the problem?  As I spoke with more developers I started to hear the same complaints, even though some were using EF, some were using nHibernate, others were using LinqToSql.  I heard the problem stated best by a guy I met at the speaker’s dinner for the Rocky Mountain Tech Trifecta.  I can’t remember the guy’s name but his words stuck with me. I was telling him that I would never use EF again if the choice was up to me.  He said it’s not that he has a problem with Entity Framework, it’s that he’s done with ORMs.  I think that’s really the heart of it.  There’s a fundamental problem with ORM as a pattern.  It just doesn’t adequately solve the problem and it ads significant complexity and inefficiency to an application.

I recently ran across a couple of old blog posts that make for interesting reading, Is OR/M an anti pattern? by Ayende, and ORM is an anti-pattern by Laurie.  I’m hearing this line of thought more often as more developers use EF and other ORMs in production apps and then have a couple of years of living with the consequences.

So it’s easy to knock something, but what’s the alternative? For me it’s been moving to a simpler data mapper instead of a full on ORM.  I first wrote my own simple data mapper, but since then I’ve discovered Dapper.net by Sam Saffron and Marc Gravel.  On the surface Dapper works almost identically to the mapper I wrote, but under the covers it’s way better and much more efficient. So I’ve been porting all of my old code over to use Dapper. 

The results so far have been fantastic.  Sometimes I have to write more code that I would have to write with a full-on ORM, but I find that I can make major application changes (relatively) quickly and easily and I have never once spent hours struggling with my persistence architecture trying to understand why I’m erroring out on an update for an object graph, or troubleshooting lazy load issues, or select N+1 issues, or thinking to myself “If only this was SQL I would know exactly how to do this”.  Instead it just works, exactly the way I expect it to, and in the end that saves a lot of time and effort.

7 comments:

  1. You make some valid points.

    IMHO the main problem is that people continue to map their object models to relational models for persistence for no good reason at all.

    The database thaw is showing us that we should only use an RDBMS for storage when we need to, not just because 'thats how its done'. I think if most developers took a look at their apps and asked 'do I really need to persist my app state in a relational database?', the answer would be no.

    ReplyDelete
    Replies
    1. I still find myself working almost exclusively with relational data, but I suspect that's due more the fact I'm familiar and comfortable with that model than it being the better fit for my apps. It is true that there's no need for an ORM if there's no R.

      Delete
  2. thanks for sharing.

    ReplyDelete
  3. How to relate all these objects which Entity Framework gives us or objects that we build? The domain entities, POCO objects, DTOs? What is the best practice when architecting a n-layered SOA based application with Entity Framework as DAL? How should be the data transfer happening between different layers? Is there a way that DTO objects can have properties that are subset of corresponding POCO or domain entity properties? or can a DTO compose of different other DTOs? What would be considerations in such scenarios?

    ReplyDelete
  4. I just sent you an email regarding everything contained in THIS blog-post. Thank you in advance! No need to reply. I will give Dapper.Net a look-see.

    -Mike DiRenzo

    ReplyDelete
  5. Hey!
    I am sure that the informative you shared through your post is useful for people. I am impressed with the way of writing. It kept connected me all the time. Keep up the good work.

    Vachel
    .NET Development Chicago
    cmscentral.net

    ReplyDelete
  6. Good writing. i'm sharing most of your opinion concerning ORM.

    ReplyDelete