Some time ago, I compared NHibernate and Entity Framework. It was from a very technical point of view, and I think it is still up to date. Today, I want to talk about the current state of things, from a less technical stand.
First, let me just say the obvious: NHibernate originated and is driven by the community, while Entity Framework is a Microsoft product. This makes all the difference in the world.
Entity Framework has a roadmap, a plan and a permanent team focused on the product, while NHibernate has nothing like this. The NHibernate community consists of some very talented programmers who spend some of their free time working on NHibernate just for the fun of it. However, it is not their main occupation, and so many questions and community requests get unanswered, reported issues pile up, parts of the codebase are really not very good and there are several remarkable features missing – the NHibernate guys used to bash Entity Framework for not supporting enumerated types, but NHibernate, in 2013, still targets .NET 3.5, does not support left joins in LINQ queries, is scarcely documented and still requires the usage of an obscure collection library called Iesi.Collections. Of course, being a community thing, anyone can jump in and help with this, and in fact, there are lots of people contributing with pull requests, suggestions and bug reports. NHibernate’s problem, in my opinion, is lack of leadership. As far as I know, it is not known if the next version of NHibernate will be 3.4 or 4, and what will be there, except, of course, bug fixes, and even less what will NHibernate evolve to, when will it support .NET 4.5 constructs such as async, and so on. The NHibernate Development list is very quiet, and these questions, as well as lots of others, have had no response to this date.
While Entity Framework’s functionality is way behind NHibernate – and believe me, it really is – it is gaining ground. Entity Framework has a leader, a well known team which makes its discussions publicly available and takes suggestions from the community in the form of requests and even code patches, some of which have already been incorporated in the main product. The next major version, 6, was announced some time ago, public betas already exist – and, of course, anyone can get the current version from CodePlex – and it points to a direction. Granted, it is not going to address any of NHibernate’s stronger points, but instead it is moving with what appears to be the current trend, namely, asynchronicity, .NET 4.5 integration and conventions.
I don’t think NHibernate is dead yet, but some things really need to change to make it a modern competitor to other O/RMs, if there is interest in it. There are other things than just functionality.
A common request when working with LINQ queries (Entity Framework, NHibernate, etc) is the ability to intercept them, that is, inspect an existing query and possibly modify something in it. This is not extremely difficult to do “by hand”, but Microsoft has a nice class called ExpressionVisitor which makes the job easier. It basically has virtual methods that get called whenever the class visits each expression contained in a greater expression, which may come from a query (the IQueryable interface exposes the underlying Expression in its Expression property). The virtual methods even allow returning a replacement for each expression found, the only problem is that you must subclass ExpressionVisitor to make even the slightest change, so I wrote my own class, which exposes all node traversal as events, one event for each kind of expression, where you can return an alternative expression, thus changing the original query. Here is the code for it:
Yes, I know, I probably should have used properties instead of events, but that’s really not important.
A simple example might be:
As always, hope you find it useful!
Back to Entity Framework Code First (EFCF) validation. On my previous post I mentioned that EFCF did not support fluent validation. While this is true, it isn’t too hard to implement one such mechanism, which is exactly why I am writing this!
I will be using the SavingChanges event to inject the validation logic, which will be implemented by strongly typed delegates. Let’s see some code:
We have an extension method that allows declaring, for an entity type, a validation expression, such as this:
This code can certainly be improved – multiple validations per entity, property-based validations, etc – but I think it is good enough to illustrate my technique.
One final note: the fluent validation will only be fired if the ValidateOnSaveEnabled property is set to true, which is the default.
Most persistence frameworks implement some kind of custom validation of entities before they are sent to the database. By custom I mean something more than just “is not null”, “has XX characters”, etc. This typically includes individual properties as well as validation of the entity as a whole – for example, checking that a property’s value is valid when used together with another property’s value.
Entity Framework Code First is no exception. Out of the box it already offers a number of possibilities for validating entities that cover typical scenarios: validation by attributes or by a validation method. One validation left out is one based on XML, but since Code First doesn’t really use XML, it should be no surprise, and the other is fluent validation, something that really should be supported.
Let’s explore each of these possibilities.
The DbContext class has a virtual method called ShouldValidateEntity that is called for each entity about to be persisted – meaning, inserted or updated –, and, when it returns true – which it does by default – will trigger a call to ValidateEntity, another virtual method. In this method, we have a chance to validate our entities any way we like. An example might be, for instance, checking if the entity to be saved implements IDataErrorInfo and extract validation information from this implementation:
For the validation to occur, the ValidateOnSave property must be true, which it is by default.
Don’t forget to always call the base implementation!
Applying Validation Attributes
Another option, which also applies to ASP.NET MVC validation (see http://weblogs.asp.net/ricardoperes/archive/2012/06/03/asp-net-mvc-validation-complete.aspx) is using validation attributes, that is, attributes that inherit from ValidationAttribute. The base ValidateEntity method of DbContext also checks for these attributes, another reason why you should always call it. Let’s see an example:
You would then apply this to some property in your entity:
The “problem” with this approach is that you must include any assemblies containing these custom validation attributes together with your model. If they are on the same assembly, there’s no problem.
By the way, you can specify multiple validation attributes and you can even apply them to the whole class, not just a property.
Another option, also common to MVC, is having your entities implement IValidatableObject. This interface defines a contract for returning a collection of validation errors for an entity. Here’s a sample implementation:
Handling SavingChanges Event
The “underlying” ObjectContext – which, in fact, is only created if requested – exposes a SavingChanges event which is triggered whenever Entity Framework is about to send changes to the database, typically whenever the SaveChanges method is called. If we handle this event, we can perform our custom validation before our entities are saved, and in case something is wrong we can throw an exception to cancel the saving process:
This has the arguable advantage that it decouples the validation process from the entities and the context themselves.
In case you are using any of these validation techniques, always surround calls to SaveChanges inside a try…catch block and look out for a DbEntityValidationException or your own exception, if you followed the SavingChanges approach. Inside DbEntityValidationException you have an EntityValidationErrors that contains all the details:
Alternatively, you can explicitly call GetValidationErrors and see the collection of errors from all sources, except, of course, SavingChanges, because the context is not actually in the process of saving changes, for all entities currently being tracked by the context.
The order by which these validation processes are applied is:
- ValidationAttribute (from base ValidateEntity)
- IValidatableObject (from base ValidateEntity
- SavingChanges (only if no errors are found)
Pick the one that better suits your needs!
This post is in portuguese only, sorry!
You will have to download and run the Configuration Console from http://www.microsoft.com/en-us/download/details.aspx?id=38789, there is no NuGet package for it. After that, you will get a context menu for each project on the solution for editing the configuration:
In some O/RMs, it is possible to specify automatic filters for entity collections such as one-to-many or many-to-many. These are applied automatically whenever these collections are being populated. Entity Framework does not offer one such mechanism, however, it is possible to implement it.
In Entity Framework Code First, entities are exposed as IDbSet<T> or DbSet<T> collections on a context, a DbContext-derived class. There is no way to automatically set a filter that will apply to all queries coming from these collections, unless we create our own IDbSet<T> class. Let’s call it FilteredDbSet<T> and have it implement the same interfaces as DbSet<T> so that it can be used instead of it transparently:
In the constructor of our DbContext, we create instances of this class, and pass a LINQ restriction query on its constructor:
From now on, all queries over the Bases collection will be restricted.
A different matter is collections on entities. For these, we usually declare a property of ICollection<T> and let Entity Framework create an instance for us, when it is loading the entity. The class responsible for creating this instance is DbCollectionEntry, which unfortunately does not allow subclassing, because it doesn’t have any public or protected constructors or virtual methods. Let’s take a different path and create our own collection class instead:
This collection receives a pointer to a possibly existing collection and a DbCollectionEntry responsible for loading this collection. We must use a bit of reflection magic to let DbCollectionEntry think that the collection was already loaded (IsLoaded), and instead load it ourselves, by applying our custom restriction to the expression returned by its Query method.
We use this extension method like this:
This will pick the Product entity from the Products context collection and filter its Details collection.
As you can see, even though Entity Framework does not have all functionality that we might be used to, it still offers enough extensibility points that allow us to built it ourselves. The same technique that I presented here can be used for building lazy loaded or even IQueryable<T> collections, both interesting ideas that I leave as an exercise to you!