Coming from working with Rails, there are things that I miss when using .NET (as exhibited by my last post). Today I’m going to tell you about a way to bring a bit of Active Record to Entity Framework.
When using Active Record, you can hook into the process at various points to perform actions. Let’s say you want to do something before a model is created, like set a date for audit purposes.
ASIDE: Audit columns of
updated_atare automatically handled by Active Record (by default). I wish this sort of functionality existed in Entity Framework, but we’ll be able to do just that if you keep reading!
Here’s a simple Rails example of hooking into the
before_create callback (This example is from the Rails docs)
Now, if there was only a way to do the same thing with Entity Framework… ;)
NOTE: You can, of course, implement your own “hooks” in Entity Framework by overriding the
SaveChanges method, but that gets messy.
In my quest to find something similar to Active Record’s callbacks, I stumbled upon the EFHooks project. This project is simply awesome! Instead of messing with overriding
SaveChanges, I’m able to inject various bits of code into the save process (e.g. Pre/Post, Insert/Update/Delete hooks). Let’s take that Active Record example from above and see how we’d accomplish the same thing using Entity Framework.
Let’s start with a
PreInsertHook. Creating a hook is just a simple class, which inherits from the EFHook class (
PreInsertHook in our case), then just override the
The EFHook classes are generic, so they will take in any object type. You can use an interface (like
ITimeStamped in the example above) or a specific class (e.g.
What we’ve said here is: “Anytime there is an insert of an object that implements
ITimeStamped, set the
CreatedAt property to the current data/time.”
All we need to do is simply call
SaveChanges() on our context.
That’s the hook, but we need to tweak our
DbContext class to tell it to use the hook. Simply derive your DbContext from the EFHooks.HookedDbContext and register the hooks.
Once your context inherits from
SaveChanges calls are enhanced to call any hooks that you have registered.
EFHooks vs. VisoftInc.EFHooks
The EFHooks project was started by Kevin McKelvin. Back in 2011, I submitted a pull request, but sadly, a new NuGet package was never published. As of today, the latest official version of EFHooks was published on 2011-09-18, and is v1.0.2.
I wanted to use EFHooks in multiple projects, and that is what spurred me to create a new NuGet package, VisoftInc.EFHooks.
Since that first change where I added the ability to use the existing context within a hook, I’ve also changed EFHooks to support stub entities (e.g to build relationships without loading objects in an MVC app). Just recently, I added .NET 4/4.5 support and changed the Entity Framework base version to 5.0.0. All of these changes have been published to the VisoftInc.EFHooks package. I’ve made these changes while using EFHooks in multiple projects. These changes have made a big difference, especially working within a .NET 4.5 project where the version of Entity Framework 5 differs between .NET 4 and 4.5.
I would be happy to push all my changes to the main EFHooks branch if Kevin will still actively maintain the project and publish changes to NuGet, but alas, for now, I use (and would recommend) the VisoftInc.EFHooks package. If you find any issues with VisoftInc.EFHooks, let me know on GitHub, or better yet, send me a pull request!