Sunday, 17 April 2011

Entity Framework - day 2

I've spent some time looking at the results again, and I've got some news.

1. Table names

Ok, if you only create a conceptual model from the database, where table names are singular, you'll get what you want - singular names for entities and plural ones for entity sets, with all the data table names preserved.
It is only when you generate database script from the model the names are changed, and all the mappings are changed accordingly. So if you work with an existing database, you'll be just fine, but if you still want to have your creation script (say, you want to deploy your application on several servers) - you probably have to accept this.

2. Lost constraints

Well, I think I can live with this in a real world.

3. Primary/foreign key names

You only have to slightly modify the database template file to get the names you want, so not a big deal at all.

4. Clustered primary key

Again, with a bit of tinkering, you get them what you want them to be, by modifying the template.

5. Lost clustered index

These can easily be added back in a manually created post-script. I don't really expect initial cript to be so perfect.

6. SMALLDATETIME changed to DATETIME

Not nice, but my bet is that this won't affect performance in any ways, assuming typical enterprise application amount of business data.


So none of these problems I mentioned look serious enough to say the Entity Framework won't do its job. The thing that concerns me though, is here:




This is not just a normal field, this is a foundation of my row-level security.
Ideally, I'd like these fields not to be in a conceptual model at all. Instead, I'd like the global filter to be added to every single query to the database I submit in my application, so I could get only rows which belong to the current user. And of course, I'd like these fields to get the name of the current user when new records are created.

It turns out there is no good way to achieve this goal in Entity Framework.

I also keep asking myself what does this "entity" do in my perfect conceptual model:


Well, obviously this one is here also because of the UserName field.
In fact, I found out it is considered as a best practice to add some extra column to any cross table, just to make sure it appears in the model, so you can add any meaningful field easily enough later. I kind of wondering at this point what was the initial idea of ORM approach - wasn't it about hiding nasty and purely physical aspects of the underlying data storage, like many-to-many-relationship implementation?

However, I this point I think maybe I should remove this field from the model anyways, since it's only giving me troubles.

I could also use some fancy way to intercept my database queries and handle this field, but... I somehow expect the framework is able to help me here.

Sorry Entity Framework. You are just not mature enough yet.

Saturday, 16 April 2011

Entity Framework

It's been quite a while since I've last updated this blog, but trust me, there were pretty good reasons for that.

Today I'm checking out the Entity Framework. I decided to give it a try, and see how it will be going.
At first I was quite happy with the results. With no efforts at all I was able to create this conceptual model out of my handcrafted database I was quite proud of:


And it seemed to make quite a good job generating my database back from the model.
However, having analyzed the results more carefully, I've come across some not really encouraging results:


1. Table names were pluralized regardless of original names being singular
2. Constraints were lost (CHECK (Color >= 0 AND Color < 12))
3. Primary/foreign key constraint names were lost (CONSTRAINT CategoryIdPK PRIMARY KEY NONCLUSTERED (Id))
4. Primary key was created as clustered
5. Real clustered index has gone (CREATE CLUSTERED INDEX CategoryUserNameIdx ON dbo.Category (UserName ASC))
6. SMALLDATETIME was automatically changed to DATETIME
7. Non-clustered indexes were created on foreign keys despite they were missing in the database (which is kind of good, and it was my fault not to create them)
8. ON UPDATE CASCADE were created as ON UPDATE NO ACTION (while it might be discussible which is right for cross-table foreign keys, still, I don’t support such an initiative).

Well, it is not like you won't be able to create a product with Entity Framework, but for sure you won't be converting your schema back and forth every so often.