Of course this post is displaying my bias, but hell, I wouldn’t have spent almost a year working so hard on Marten if I didn’t believe in the concept and its advantages over other .Net persistence tools. In no way am I actually criticizing Entity Framework or Dapper in this post, but I am trying to bluntly say that the days of ORM’s and even micro-ORM’s needs to come to a close soon.
Last week I got to pull the trigger on Marten 1.0. This week I think it’s time to talk about why and when you would want to use Marten as your persistence strategy in .Net development. Most of the early interest and adopters of Marten have been disaffected users of RavenDb looking for a more reliable alternative who were already sold on the idea of a document database (and here’s me from a month ago on moving from RavenDb to Marten). That’s great and all, and it got our community jump started, but I think Marten deserves a longer look from developers who aren’t already using document databases like RavenDb or MongoDb today.
I’ve written about my thinking about how I choose persistence tools before. I’ve also spoken out many times about the never ending attempts to keep business logic code from being compromised by coupling it directly to your database storage. Finally, there’s the old discussions about “persistence ignorance” from years past.
Consistent with my beliefs and experience with software development, I feel like the document database approach for most of your application persistence makes the most sense for developer productivity, automated testing support, and ease of deploying application code changes. Yes, please do consider Marten as a replacement or alternative to MongoDb or RavenDb because it’s built on the more reliable and performant Postgresql foundation. But also, give Marten a serious look as an alternative to using the Entity Framework, NHibernate, or any of the plethora of micro-ORM projects out there.
Why you would choose Marten over EF
- Much less mechanical work for mapping and configuration. Far less effort for schema management and database migrations.
- Higher “reversibility” in your software architecture because it’s so much easier to change the structure of your documents with Marten versus an ORM of any kind.
- Marten is built on Postgresql and gets to take advantage of their very advanced JSON features. Postgresql is highly performant, widely used, runs cross platform, and it’s FOSS.
- Marten is going to be able to handle hierarchical data and storing subclassed documents much easier than any ORM ever could. Moreover, Marten will easily outperform an ORM fetching any kind of aggregated, deep object because there’s just far less stuff that Marten has to do compared to an ORM like EF.
- Marten allows you to mix and match persistence strategies. Document storage? Check. Event sourcing persistence? Got that too. Wanna use straight up SQL or even integrate directly with Dapper in Marten database transactions? We’ve got that one covered as well. Heck, if you wanted to do full text searching or do key/value storage, you can use Postgresql features to get that done all in one single bit of infrastructure.
- Using value types is trivial in Marten. As long as your JSON serializer can handle your type, you’re good to go with no crazy gymnastics like ORM’s cause.
- I think that Marten’s compiled query feature is hands down better than EF’s solution for reusing Linq query parsing, and that’s goint to make a significant difference in application performance under a load.
Why you would choose EF over Marten
- You don’t have any experience with Postgresql
- The full weight of Microsoft is behind EF whereas Marten is a community OSS project. My company is de facto sponsoring Marten and I have a track record for sticking with my OSS projects for a long time, but EF has a whole team behind it.
- EF’s Linq support is going to be more complete than Marten’s — but we’re certainly trying on that front.
- Entity Framework and relational databases are very well known and it’s easy to find folks who are familiar with them. Like it or not, that has to be part of your thinking about choosing any tool.
- More documentation, samples, and a larger development community than any OSS tool in .Net could ever attract.
- Your shop simply favors Sql Server or uses cloud hosting providers that only support Sql Server. We’re frequently getting the feedback from developers that they’d like to use Marten but that their database teams won’t allow Postgresql. I think that there will eventually be a version of Marten on Sql Server, but that’s dependent upon Sql Server getting better JSON support than what’s coming in MSSQL 2016.
- You can still use straight up SQL to access your Entity Framework persisted data if that’s valuable. You can do that with Marten as well, but the Postgresql JSON operators aren’t the most approachable thing in the world.
A decade ago I strongly espoused Object Relational Mapping (ORM) tools like NHibernate as the “best” tool to allow us to build our application code in a way that made sense for the application logic and still be able to persist state to a relational database. Great, and that was arguably better than the morass of purely procedural code and wretched stored procedure data access that came before. After using ORM’s for five years, then another five years of predominantly using document databases, I don’t ever want to go back to ORM’s.
Why? Because ORM’s are a giant mess to use if your object model deviates much from the structure that makes sense in the database — and it usually does. I’m sick of wasting time trying to remember to make every member virtual for dynamic proxies, sick of having to worry about lazy vs eager loading, and having to duplicate so much logical work to keep the application code synchronized to the database schema. I absolutely prefer the productivity we get from document database approaches where we just store a JSON representation of our document objects with minimal work for mapping.
While the classic analogy for ORM’s is Ted Neward’s seminal blog post on ORM’s are the Vietnam of Computer Science, the analogy I would use is that ORM’s are like Prius’s. I think they were only an overly complicated, intermediate solution until we came up with better approaches. Much the way that hybrid cars are a stepping stone to fuel cell or pure electric cars and Obamacare should be a temporary measure until we get our acts together and adopt a rational single payer healthcare system, ORM’s are just a less bad idea than what came before.
I helped write the EF Vote of No Confidence once upon a time, and while I to this day think that the initial version of the Entity Framework should have never been released, I don’t actually have any issue with the current versions of EF and how it implements object relational mapping. I’m just objecting to the whole concept of ORM’s now;)
What about Micro-ORM’s?
I occasionally see one of the main developers on Dapper pooh-pooh’ing IoC containers like StructureMap.* That’s okay though because I have the exact same “meh” attitude toward micro-ORM’s. I think they couple your application way too tightly to your database structure and they seem to let database concerns bleed into your application code more than I’d prefer. Again, the problem with ORM’s is the “R” more than how the “M” is done.
It’s a moot point though, because you can happily use Dapper in conjunction with Marten by just calling Dapper methods on the exposed connection property of Marten sessions — which was done explicitly to enable this interaction.
* I don’t feel strongly enough to even argue the pro-IoC container side of things. I’ve thought about kicking out a blog post titled “A tepid defense of IoC containers.” My own usage of StructureMap is pretty simple anyway.