More Entity Framework thoughts

Dan Simmons has a great write-up on Microsoft’s vision of Entity Framework that really gives some insight into the motivation behind a lot of the direction that they’re going in.  Go read that post, and come back.

Back now?  OK good.  I like to pull quotes out, and I don’t like to pull them out of context, so it’s best to read the original post or I might seem like a bit of a tool for doing so.

The quote that showed me the direction the best was:

The EF was specifically structured to separate the process of mapping queries/shaping results from building objects and tracking changes.  This makes it easier to create a conceptual model which is how you want to think about your data and then reuse that conceptual model for a number of other services besides just building objects.

The emphasis added is mine.  Dan then goes on to describe the different ways you might reuse the conceptual model, from reporting, exposing RESTful services, online/offline models, etc etc.

Those are a LOT of different concerns to be talking to the same database.  Although a mapping layer provides a translation, it’s still talking to the same database.

My comment on his post was:

I think it’s a mistake to share a data model with anyone outside your bounded context (see Evans, Domain-Driven Design).  It’s also a mistake to share a conceptual model or a EDM or whatever we’re calling this.

I never want domain objects exposed directly via services.  That’s violating the encapsulation I’m trying to create.

If someone wants SSRS, then I give them a separate reporting database, tailored to reporting needs.  I don’t want reporting concerns bleeding into my transactional concerns.  A mapping layer will not solve this problem, products like SSIS can.  You want reporting? Here’s your read-only view, updated every hour, five minutes, daily, whatever.

Sharing a connection string is sharing a connection string, no matter how much lipstick you put on that pig.

You’ll get nothing but trouble if you share a database connection string, no matter how many layers you put between them.  Because eventually, some consumer of that data will want some change in the database (not just the conceptual model).  Not maybe, not in edge cases, but always.

Personally, I’d much rather go for the Domain-Driven Design style Bounded Context, where I have Anti-Corruption layers between different domains.  Sure, an Order entity might have the same identity from context to context, but that doesn’t mean the conceptual model stays the same.

And how would you manage and maintain those conceptual models, when so many folks might need change?  You’d have to shape your organization around your conceptual models to be able to handle the feedback and change requests from the different groups using your One True Model.

The EF goal is well beyond simple ORM.  It’s an Object-Relational Mapper Mapper.  You map your ORM to another conceptual map, which maps to the data model map, which maps to the database.  The “just building objects” part tells me that EF is seriously discounting the idea of a rich domain model, which is where the heart of my business logic is.

There, and in stored procedures of course.

About Jimmy Bogard

I'm a technical architect with Headspring in Austin, TX. I focus on DDD, distributed systems, and any other acronym-centric design/architecture/methodology. I created AutoMapper and am a co-author of the ASP.NET MVC in Action books.
This entry was posted in EntityFramework. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Blake C

    Jimmy, layin’ the smack down on EF, ftw! Good stuff.

  • The whole Order entity from context to context is an excellent point. Only the behaviour of one particular implementation knows that context, the “EDM” can’t and shouldn’t (in case some one’s listening and thinking “if we just add the ability to attribute context to entities and allow them to have the same name these guys will be happy…”) know about that context.

  • DaveTheNinja

    I got $10 on Jimmy!

    Dave The Ninja

  • Good points!

  • “I don’t want reporting concerns bleeding into my transactional concerns”
    My problem with this statement is that it sounds a lot like religious zeal.
    As far as your users are concerned they want to “report” on their “transactional” data. I would venture to guess that 90% of business apps are running on hardware that has more than enough processing power to transform the transaction data into a reportable format within the required performance constraints.
    IMHO building a data warehouse for reporting is a performance optimization, not a seperation of concerns. Making the blanket statement that they should always be seperated is unwise.

  • @Darrel

    Wanted to reply directly through your blog…oh well, comment will have to do!

    First off, I’d like to separate the idea of querying/searching from reporting. These are two different use cases, and most likely different user roles. Perhaps analyst and sales reps for example.

    Querying is a valid concern, where I’m returning back one or more entities that belong to you. Writes need to be fast here.

    Reporting is a different concern, where I’m returning aggregated, de-normalized information optimized for reading, grouping, and quickly analyzing.

    In this scenario, a separate reporting database is definitely a separation of concerns. Reporting users will want their data a certain way. Maybe # of orders this month, grouped by Region, then by State. That’s not something easily done in a transactional manner.

    Different users, different user roles, different concerns..that need to be separated? Anyway, most of the time I’ll put the reporting database riiiiight next to the transactional one. Logical != physical modeling, right?

    It is an optimization, but an optimization about the “Asks” I’ll get from either user type. The reporting user will want good aggregation, while the querying user wants fast searching (and fast writes). I’d rather not compromise one user’s concerns because it contradicts the other.

    Hope this helps!