Monday, February 15, 2010

Entity Framework 4 - The light of .Net ORM dawn?

For 60 years in IT, there are lot of the ever repeating questions in every project.
Among them:

In what format I do send my data to the consuming system?
Well, finally we solved this.... That's XML. Checked.

How do I get my data to the consuming system?
Well, that's WCF for all .NET folks. Checked.

How do I load/persist my object in my relational database?
Well, hmm, uhhh.

I promise the number of different relational data access/persistence implementations in .Net are only little lower than the number of .Net apps running on this planet using that technology. How we do data-access is a question of the style of each developer and thus dependent on the person not the technology. This of course is additional risk to every .Net project at a quite low level.
Compared to Java, in the area of ORM .NET seems to be light years behind. What Microsoft shipped as Entity-Framework 1.0 was as good as the WF-WCF 3 integration or in other words.... simply beyond every comment. But with is the upcoming .Net 4 ships the new Entity-Framework 4. So is there finally the light of dawn coming into the .Net ORM world?

I tried it and the result was bringing me back to earth quickly. Guess you have

class B
{
public string Id { get;set }
}

class A
{
public string Name { get;set }
public List<B> Bs { get;set;
}

and you want to map this to a database you find out that...

you cannot do that with the standard approach of Entity-Framework 4. Here you can only move a property from entity A to B if there is a 1 : 1 relationship between those tables.

Out of the box EF4 is just a lazyload DataSet 2.0 with autogenerated query,update, insert commands. But it is nailed on my relational tables. The other problem I see here is that out of the box EF4 currently supports SQL-Server only. If you want other database support you need 3rd-party provider.

From an architecture point of view this is good enough for "Click and Shoot" applications, but not for serious applications that require abstraction of the data from the underlying storage.

If you want to use EF4 in this scenarios, you need to switch to POCO mode. It looks like you have to sacrifice most of the the tools and code generation support though. There are some POCO templates for code generation, but if I look at the known defects list, this whole thing does not look quite production ready. It looks like the EF evolution from DataSet 2.0 to an serious ORM tool is ongoing, but I would not make a bet it happens with this release. So hopefully with EF 5 we can expect some more mature solution here.

Meanwhile related to true ORM instead in the light of dawn we have to walk in utter darkness?

No.

I looked into NHibernate lately and although it does not completely meet my (too high?) expectations of an *Object* Relational Mapper, you can do a lot more things with it than you can do with EF4. It really feels like a mature ORM framework to me.

So I cannot map the exact above example but at least I can map what gets me at least to the same usability I intended.

class B
{
public virtual string Id { get;set }}
}

class A
{
public virtual string Name { get;set }
public virtual IList<B> Bs { get;set; }
}


This is pretty much a basic problem for NHibernate. But you can solve a lot more problems with it, like inheritance, cyclic references, Write/Read batching (in other words performance tuning),it supports lazy load with different proxies...
There is a (not quite impartial) comparison of Entity Framework 4 vs NHibernate. The comparison ends with the pro's of EF4 being "A better Linq provider and it's from Microsoft".
The downside of NH is of course, that is not just "Import tables" click and shoot. As you have some choice on the mappings you have more complexity and more handwriting and configuration.

Maybe I have to give up my idea of *the* ORM. It seems you have to forget about the "O". The best that can be done is an "E" or "Entity" Relational Mapper, where "Entity" is a technology related subset of "Object". And the the bigger your subset is the better is your ERM tool.

9 comments:

Daniel Simmons said...

If you prefer to use nHibernate, then more power to you, but I don't know where you got the idea that EF4 can only support 1-1 relationships. I just wrote a small program against EF4 RC with exactly the class definitions in your sample, and it works just fine.

- Danny

elLoco said...

That's good to hear. I tried this in Beta 2 and will try again in RC.

elLoco said...

I checked with RC and still see no way to map a table to a List.

Take the following example:

You have the tables Order, Customer, OrderCustomer. A classic m : m relationsship between Order and Customer through association table.

Now show me a model without an entity OrderCustomer, but a class Order that has a List<Customer>.

This is <many-to-many> in NHibernate.

Believe me. Entity Framework 4 is DataSet 2.0. It's designed relational or it's an ORM tool without O&M. Compared to NHibernate this is toy class. Microsoft should stop wasting their and our time, and instead contribute a good Linq provider for NHibernate. I am sure once you tried NHibernate you agree to this.

Daniel Simmons said...

I don't know where you are looking for your information. This is totally supported. Both the poco support and the ability to have many-to-many relationships. Again, if you prefer to use nHibernate, that's fine. I just don't want people to have misinformation. For example, have a look at this URL: http://msdn.microsoft.com/en-us/library/bb399189(VS.100).aspx

elLoco said...

Maybe we are looking from different angles. My perspective is from the object side ("how do I get my relational data into *my object*"). I assume your view is from the database side ("how do I get *my relational* data into some object"). In this case all these relations are supported on the relational side, but with out of the box Entity Framework 4 not on the object side. There I can only move a property from entity A to B if there is a 1 : 1 relationship.

But here is what I was basically looking for. It is coming with the POCO support. I'll revise the article accordingly.

Anonymous said...

DataObjects??

elLoco said...

Thanks for the link! I will try it.

Anonymous said...

I agree with everything that you said on ORM's. The one additonal point I would bring us is performance. We write highly batch oriented systems and it is hard to tweak and design ORM's to be able to mee that type of needs.

My question would be where can I go to find more information on non-ORM solutions. It seems like all of the hype is around ORM's now and no one is talked about writing your own data access layer with the newest patterns and techniquies.

I would really like to look into generating the mapping between the data results and my objects while writing my own queries for performance.

elLoco said...

As far as I looked I found NHibernate is by far the most feature complete. 2 Month ago I used NHibernate 3 Beta 2 with LINQ Support and I really loved it. It also gives you the opportunity to use your SQL and does the mapping for you. I think ORM are basically popular for a reason. In a scenario where you want to store an object to a database they can be really helpful. Let them create the tables for you and you cannot have a messed up schema. But things get already difficult if you want to map to your custom object from an existing database. ORM's can be a fast road to hell here. Also where high performance is required ORM's are probably not an option. The fastest NHibernate can get compared to ADO is I think around 30%. But for many scenarios this should be sufficient.