views:

380

answers:

1

I've recently inherited a system that relies heavily on an EAV database structure, and is really struggling from a performance perspective.

What I want to do is use nhibernate or another suitable ORM product to map these EAV tables to entities in such a way that we can map a row to a property. We can then refactor the database in order to make it relational. Does anyone know if this is possible? An example would also be appreciated! :)

To give you a feel for the structure, it looks something like this:

Entity (EntityId) EntityVarchar (EntityId, VarcharValue) EntityFloat (EntityId, VarcharValue)

and so on. If I had a Customer entity I'd like to say Customer.Name to get the name rather than Customer.Varchar["Name"].

Please note there is no need in our system to use an EAV model, we don't allow runtime changes to data structures, and I believe it's a bad practice anyway.

A: 

I don't think this will be that easy. Though there are generators able to read a database schema and generate appropriate mapping and classes this would only result in an access layer for your existing eav db. To generate a relational version of this db you then would have to read the data and create new domain objects containing properties for the the values set in your db. This could most likely result in one big table containing all the properties exist in the eav db. Therefor I think a better approach would be to create a relational DB model by hand analysing the existing data and considering the needs of your application. Especially Table inheritance should be your friend here. Then after you have created access layers for both schemas you still would have to write a mapping for data migration.

zoidbeck
With nHibernate you can map entities to classes in such a way that it isn't a 1:1 mapping with the db schema so you don't have to strongly couple yourself to the database.I just can't see a way at the moment of mapping multiple rows, one for each property to a single object. Typically you'd have one row which contained the data for a single object.
spooner
I know, but i don't see any possibility to do what you want in an other way than that you already mentioned. You are able to use filter-prop on many-to-one's but imo that wouldn't help anything, also i don't think this would help to fix your performance problem anyway. Maybe i got you wrong but as i understood you are considering to refactor your eav to a relational or mixed schema. If you only keep the rare props as eavs in a bag/set you could make them lazy to only load on demand.
zoidbeck
The issue is we really don't need a property bag, it's only our developers who will add new properties, we don't expect a user to extend the model.Basically the system I've inherited is built off a framework with this EAV structure in place. We want a totally normalised model going forward. I was hoping that we'd be able to perform a mapping in the way I suggested as we could then baseline the domain model and then start doing the database work.From what you are saying this isn't possible, which is a shame, as it seems the only other solution is a hand crafted DAL.
spooner
Mayby that's why it is called an object-relational mapper :)...And yes that's the point: You don't need it so get rid of it. The more time you invest making it work little better/faster the less you'll have gettin a proper db schema and DAL. I really don't think you will get rid of performance problems until you face the database issue.Read here (especially ayendes comment): http://www.bestguesstheory.com/2009/06/nhibernate-eav-system-search.html
zoidbeck
Thanks for your help. I'll look into starting from the database end first, which is obviously the real problem here, then we can apply an ORM.
spooner