We’re talking past each other on the Entity Framework

Yeah, I know everyone is tired of the Entity Framework argument, but maybe we can start a real discussion.  I’ve seen two very different conversations about the Entity Framework from the data centric folks (pro) and the DDD/TDD/OOP folks (con).  It’s not even a real argument, because we’re concerned about very different things that aren’t even in real opposition.  I’m completely agnostic about the Entity Data Model and the farther reaching, universal data access goals of the EF.  I’m strictly concerned with the EF’s poor applicability for evolutionary design, Domain Driven Design, testability, and separation of concerns.  The EF seems to have all the major bases all covered in terms of functionality, it’s just the *way* that it implements this behavior that concerns me.

The problem with the blogging from last week is that it’s two different conversations!  The “pro-EF” folks seem to be giddy about the functionality and features of the EF.  I’m steamed about what I feel to be the poor usability of the EF.  I do fully understand that the EF is about so much more than O/R mapping, I just don’t think that their vision for data access adds more value than the harm that EF will do to my architecture by being intrusive.  The cool thing is that the EF team *can* actually make both camps happy.  There is absolutely no technical reason that the EF cannot deliver all
of this utopian EDM goodness AND make the necessary structural changes
to allow for real Persistence Ignorance to address my concerns about
its usability. 

The only real argument is their priority queue.  I obviously think the EF team needs to get a full Persistence Ignorant story in place before adding any other new functionality.

For the record, I’m somewhat dubious about the actual usefulness of the Entity Data Model, but I will very seriously consider using the Entity Framework the minute that the EF team ships a real Persistence Ignorant option (which HAS to include transparent lazy loading) and a streamlined mapping configuration story (i.e. I want the conceptual model completely hidden away).  Until then, all that impressive sounding EDM stuff does not justify what I feel are severe compromises in my application architecture that do not occur with other persistence solutions. 

About Jeremy Miller

Jeremy is the Chief Software Architect at Dovetail Software, the coolest ISV in Austin. Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy is the author of the open source StructureMap tool for Dependency Injection with .Net, StoryTeller for supercharged acceptance testing in .Net, and one of the principal developers behind FubuMVC. Jeremy's thoughts on all things software can be found at The Shade Tree Developer at http://codebetter.com/jeremymiller.
This entry was posted in Database and Persistence. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Graham

    Err, Lucas how are you embedding “SQL-like” syntax all throughout your code?

    That’s the point of the framework mapping to classes… and using an object-driven approach to working with your data.

  • http://colinjack.blogspot.com Colin Jack

    @Frans
    If lazy loading bothers you then the unit of work approach must too, in that you can persist updates without going through a repository.

  • Lucas Goodwin

    I still don’t get what the hoopla is over the EF. Oh boy, now I can embed SQL like syntax inside my app and propagate it all OVER the place. Yeah, and I want to do that because….

    Seriously? What’s this supposed to do for me? DataSets are un-maintanable so we abandoned those. WebForms are incompatible with the way the internet really works, so we abandoned those. How’s EF any different?

  • http://www.blogcoward.com jdn

    Scott:

    Interesting idea. Wondering about logistics.

  • http://scottic.us Scott Bellware

    jdn,

    Why don’t you get on a project with Jeremy and put your hypothesis to the test?

  • http://www.blogcoward.com jdn

    Jeremey:

    I am not questioning that exactly. Blog comments are incomplete.

    There’s transparent and then there’s transparent. I don’t have an argument (here anyway) that from a certain perspective, there is more friction from that perspective. I think that there is.

    I do believe that Castle/NHibernate do things the way that they do for good reasons. Very good reasons.

    But they aren’t universal. ‘Friction’ like ‘Separation of Concerns’ is a relative concept. If you peruse your own blog posts, you will find places where you say something like (paraphrasing of course) “This may seem like I’m combining concerns, but I think it is okay for reason X” where ‘X’ is something you’ve seriously considered and decided it was okay in that situation.

    It would be good if there was a forum where we could discuss it more directly. I’d be willing to setup something where we could do that. I could give you my number through email if you like and we could go through things in a more interactive fashion.

    It might be enlightening. YMMV. I’m willing to make the effort.

  • http://codebetter.com/blogs/jeremy.miller Jeremy D. Miller

    @jdn,

    I did very clearly say TRANSPARENT lazy loading, as in THE BUSINESS CODE DOESN’T KNOW ABOUT THE PERSISTENCE INFRASTRUCTURE.

    TypeMock isn’t the best answer here. With the NHibernate style Virtual Proxy approach, I can do pure state based testing in unit tests. TypeMock might make it *possible* to unit test without the database turned on, but it’s still more friction in setting up unit tests than the comparable NHibernate solution.

    Besides friction, the TypeMock setup code would be noise code in the unit tests that would distract from the readability of the unit test/specification.

    Castle/NHibernate do it the way they do it for a good reason. The “meat” of this issue, Mr. Phd, is friction. Separation of Concerns is the bedrock of good software design. At no point did I say the words IoC/DI here, did I?

  • http://www.blogcoward.com jdn

    Jeremy:

    I understand that point, but that’s a separate complaint. You can do lazy loading. I would raise the name of ‘TypeMock’ about the testing point, but, well, we’ve seen the last week or so .

    More seriously, it seems more and more to me that the complaint against a lot of EF and Microsoft in general is that, to be simplistic about it, it doesn’t do things the way the Castle stack does things.

    Which I think is accurate. I’m hardly an expert about the Castle Stack, but that seems pretty obvious. I just think maybe people would talk less past each other if they put it into such ‘base’ terms.

    Persistance Ignorance is a myth, DI/IoC is not a universally good ‘design pattern’, etc. It would be nice to lay out the real meat.

    jdn

  • http://codebetter.com/blogs/jeremy.miller Jeremy D. Miller

    @jdn,

    The link you mentioned doesn’t solve the real problem. It reduces the external code and the calls to “Children.Load,” but you’re still screwed because the business logic and navigation to the children cannot function without EF up and running with a configured data store. Testing would be laborious here, and that’s just as big a gripe as the noise code from EF out of the box.

    NHibernate and I would assume the other tools deal with this by using Virtual Proxies for the collections. In that case, the parent object only knows that it has a child collection, and can happily use List in unit tests, and NHib will stick in the virtual proxy for IList at runtime to perform the lazy loading on demand. No extra work on my part other than in configuration.

  • http://codebetter.com/blogs/jeremy.miller Jeremy D. Miller

    @Frans,

    3 different arguments then. I’d strongly agree with you and your longer post last week that there needs to be a serious debate about whether or not the EF is actually any better than the existing tools.

    As Chad said, the repositories are only for accessing the aggregate root. I get an Invoice from a repository, but any type of InvoiceDetail should come by navigating Invoice itself. Internally, if Invoice needs to perform an aggregation of some sort over its children, it certainly shouldn’t be touching repository infrastructure directly just to get its own children.

  • http://chadmyers.lostechies.com Chad Myers

    @Frans/@Steve:

    My understanding is that the Repositories are the gateway to the aggregate and no more. Relationship/reference loading is a mapping/ORM concern and not the responsibility of the Repository.

    However, in certain circumstances, which fetching strategy to use is subjective based on the context in which case the Repository can provide a fetching strategy for that particular query to the ORM so that the ORM knows which objects to pre-load (vs. lazy load).

  • http://blogger.forgottenskies.com Steve Gentile

    Interesting comment Frans. I always thought the same as well. All the work to use the repositories, but then the lazy load goes around it :)

    Linq to Sql has a SqlMetal flag to create mapping files vs. attributes.

    From MS perspective I think their overall stance is that their tools will provided generated code.

    If you want to build on top of that generated code, you must use partial classes.

    This would mean creating domain specific code in partial classes separate from the code generated soup.

    If you look at ActiveWriter – it does the same.

    So we have the ‘drag and drop a 100 tables to the GUI’ ORM or the ‘hand craft 100+ hbm.xml files’ .

    I agree Jeremy, seems it wouldn’t be too much to ask to have a build flag that puts the database metadata in a separate file vs. in the classes.

    I guess maybe they are appealing the typed dataset/table adapter approach (which I abhor, but many MS shops use)

  • http://weblogs.asp.net/fbouma FransBouma

    I always find it a bit ironic that pro-DDD people want lazy loading so bad. If you look at it: lazy loading goes against DDD principles: it fetches related entities into your object graph by bypassing the repositories. Unless you write the lazy loading code yourself to use the repositories, but that wouldn’t be ‘transparent’.

    So as soon as you allow lazy loading to happen inside your application, someone can mis-use it and bypass repositories. Unless additional code is written to make sure repositories are used instead of a direct fetch. But ‘transparent’ would suggest that it’s there and works out of the box.

    As an active participant in the EF discussion last week (and not one of the pro-EF people btw) I didn’t see 2 camps discussing different topics really. It was about the same topic: is there a real, fact based, reason why the EF is something better than the established mature O/R mappers out there? The pro-EF people said ‘yes’, the nay sayers said ‘no’.

    To me, the only argument the pro-EF people have is that an EDM can be used in various MS products without any effort. However that’s not unique to the EF, you can do that with other O/R mappers as well.

  • http://www.blogcoward.com jdn

    http://blogs.msdn.com/jkowalski/archive/2008/05/12/transparent-lazy-loading-for-entity-framework-part-1.aspx

    You can implement lazy loading if you want to. You can’t clicky-clicky drag n’ drop and get it, but that shouldn’t bother this crowd.

    “You have the EF folks and their fans over on the left, cheering about the one entity model to rule them all, and you have everyone else over on the right ”

    The people on the left out-number the people on the right by 10-1, at least.

  • Jeremy Gray

    @Core – it isn’t “wishy washy”. EF doesn’t support transparent lazy loading. Every other ORM/”data mapper” worth its salt does. There ya go. There’s nothing else that needs to be added. I fail to see the “wishy washy”.

    Jeremy is right however, in that the two groups (assuming we simplify the landscape into two groups) are simply talking past eachother at this point. You have the EF folks and their fans over on the left, cheering about the one entity model to rule them all, and you have everyone else over on the right saying “I highly doubt the one entity model to rule them all is even a good idea, totally ignoring for the moment that this thing is invasive, has no persistence ignorance, and is missing fundamental functionality like transparent lazy loading.” The concerns are running so orthogonal to one another that it is almost like the two groups aren’t even in the same conversation.

  • Core

    >doesn’t really support lazy loading the way a typical
    >ORM would.”

    ??

    I keep trying to find the substance at the heart of alt.net’s criticisms of EF. But this kind of wishy-washy prose turns up everywhere.

  • http://www.dotnettricks.com/ fregas

    You know, i can understand PI not being a top priority from Microsoft’s point of view (it ties you even more to their product and way of doing things) but i don’t get why true lazy loading was ignore.

  • http://codebetter.com/blogs/jeremy.miller Jeremy D. Miller

    @Erik,

    Other way around. Linq to SQL apparently can be used in a PI way, it’s just not the default. See Scott Allen’s and Ian Cooper’s blogs for the details.

    EDF does all the version tracking in the entities themselves, and doesn’t really support lazy loading the way a typical ORM would.

  • http://scottic.us Scott Bellware

    We stop talking past each other when we stop talking about the Entity Framework in abstract and in theory, and start talking about using it in entity-oriented .NET software applications.

  • Erik

    I thought EDF allowed for persistence ignorance – this was one of the main arguments against LINQ to SQL…