Tuesday, October 4, 2011

Entity Framework - A Review in Practice

I started playing with EF with .NET 4.0.  I came into it with a reserved attitude - my coworkers shoehorned it into a new project we were working on; I was more comfortable with ADO.NET, and was skeptical that it would make our lives easier as it was supposed to, but as a professional geek I have a responsibility to give new tech a fair shake.  Now I have used and am currently using EF for a number of projects that I am working on, and I feel comfortable giving my two cents about the product.

Coming from a strong DB background, I prefer to model in the database environment.  Conveniently, the EF model generator supports this.  You build your schema, define your keys, create your relationships and stored procedures, and then, once your data model is complete, use EF to generate your object model for use in code.  Invoke a couple T4 templates, and you're off, cooking with gas.

The support for this is pretty good as long as you are not doing anything esoteric in your data model; of course, in almost any business application, there is usually a few things that are... off.  Business object models rarely have the consistency that data object models do.  The instant you step off the beaten path with EF, you are in a world of headaches.  The one-offs are dangerous, because all that time you spend just trying to get your model to validate eats up what you would have saved if you had used a more primitive but flexible mechanism.

Trying to get a model to validate with one small difference from what EF thinks you actually want has caused me to scream at my computer loud obscenities at all hours of the night.  Good thing I live alone.  The EF interpreter of the schema is sophisticated, but not flexible, and if you are fairly versatile in the way you build your schema, EF is likely to frustrate the hell out of you.

All bitching aside, one of the good things about EF is if, as you go along, you realize you need to add a column to a table that is referenced in six other spots, you can, with very little difficulty.  This is a huge timesaver over editing a dozen stored procedures, and why I still use EF despite the effects it has on my blood pressure.

Integrating your object model into a UnitOfWork pattern is fairly straightforward, although I have to admit the first few times we tried we way overthought it until we'd painted ourselves into a corner, and had to rip it all out and start over again; I think this had more to do with us not really understanding the UnitOfWork pattern, though, and less with EF.

One problem I had with EF was the way it handles child objects in the graph.  The .Include() method adds the child objects to the target object from the repository with the relative ease you would expect from an ORM; God help you if you want to alter those child objects as they relate to the parent object, though.  It's possible to do, but completely counter-intuitive, and detracts from the benefit of the ORM model, which allows us to treat data as objects since we tend to think that sort of way.  With all of the automation involved in the underpinnings of the EF object repositories, you'd think they'd have a much more elegant way of handling this... but they don't.

Another issue I had was with portability.  There were times I wanted to take a full object graph and transport it to another system.  The actual data was serializable; the underpinnings of the "glue" that held the object properties together (navigation properties) were not, so much.  To me, it would make perfect sense to allow the developer to define a key translation behavior (do I keep this identity-based key, or make a new record?) and insert/update an entire graph from another system.  Portability and generics are not well supported in EF.

The biggest thing I don't like about EF is there is no concept of a "JDI button"... where JDI stands for "Just Do It".  EF will try to validate the model against the database, and against its own internal configuration, but it's very sensitive, and if it encounters a case where it imagines something could go wrong, it will not allow you to proceed, even if you know the condition it is worrying about will never occur, based on business logic or the data being transformed before it got to that point.  Everything is an error, and the errors are cryptic and vague... and not well documented.  Just make it a warning, let me deal with the problem when (if) it actually is a problem.  Please!

An interesting "bug" I've seen with EF is the way it sometimes handles relationships... there are times when several foreign key relationships are designed in exactly the same manner, but are interpreted differently in EF.  A manual tweak will make the problem go away, but it's bizarre to see it in the first place.

The way the EF lays out the object model is nothing short of bizarre.  Luckily, you can reorganize the model, and it will remember your change.

All in all, I am not happy with EF in its current incarnation, but I still use it because for the most part it is better than the alternative.  Still, by version 4 I'd expect a far more mature product.

No comments:

Post a Comment