Entity Framework is a standard tool for .NET developers. I have quite an appreciation for it since I had the unfortunate opportunity to do database work without it in the past. All of the desktop applications I wrote at home while transitioning from graduation to employment relied on ADO.NET data providers - the tech used for database related work in .NET before ORMs became common. Things didn't change much when I got my first job as I spent quite a lot of time working on older ASP.NET Web Forms applications that were also lacking an ORM. So the times when I did get the chance to use Entity Framework I was a happy camper.
Like any other ORM, Entity Framework is first and foremost a productivity tool. It helps us do more work in less time. Which in term saves time, which in term saves money. This is an important thing to understand and it leads me to my point. Entity Framework makes me a faster developer, not a better one. It helped me write code that was easier to maintain when I was inexperienced and knew nothing about maintenance. It helped me write complex queries when I was terrible at SQL, and did migrations for me when I couldn't bother to do them myself. And now that I've gained some experience, Entity Framework no longer makes me a better developer.
Although I still consider EF to be amazing when it comes to the productivity boost that it provides, when I'm working on my home projects I don't care how long it takes me to do something so long as I do it well. So in my daily read up on tech I eventually came across a post claiming there was an ORM that is five to ten times more performant than Entity Framework. I wouldn't say that I was surprised with the performance results as Entity Framework is notorious for being slow in comparison to other ORMs.
Now take heed, Dapper is not like Entity Framework. It won't fix all of your data layer problems and your marriage. It is a bare-bones version of an ORM. A micro-ORM as it's authors StackExchange sometimes call it. This is why it's so blazingly fast. Its feature set is small but not trivial. It can help you:
- Execute queries returning multiple rows, a single row, scalar values, or no results.
- Parametrize queries
- Map query results to objects
Dapper doesn't have its own syntax, you write SQL. So since the veil of abstraction is so thin you get comfortable with it in no time. Testing what you wrote is as simple as copying and pasting it into Management Studio. But what good are words without an example.
Here's a comparison of doing some basic SELECT
queries in Entity Framework VS Dapper:
// Entity Framework
using (var ctx = new SongsContext())
{
List<Song> songs = ctx.Songs.ToList();
// Single
Song song = ctx.Songs.FirstOrDefault(x => x.Id == id);
}
// Dapper
using (var conn = new SqlConnection(_connectionString))
{
List<Song> songs = conn.Query<Song>(@"SELECT * FROM [Songs]");
// Single
Song song = conn.QueryFirstOrDefault<Song>(@"SELECT * FROM [Songs] WHERE [Id] = @Id", new { Id = id });
}
And here's a Dapper example of an INNER JOIN
:
using (var conn = new SqlConnection(_connectionString))
{
List<Song> songsWithArtists = conn.Query<Song, Artist, Song>(sql,
(song, artist) =>
{
song.Artist = artist;
return song;
}, null, null, true, "Id");
}
You probably noticed that Dapper is more verbose. This is because its mapping mechanism is more primitive than the one that Entity Framework employs so there's a bit more boiler-plate to it. But the extra code that needs to be written is usually negligible. It kind of puts into perspective how much of the work Entity Framework does for us under the hood.
Let's take a look at inserting in Dapper.
using (var conn = new SqlConnection(_connectionString))
{
conn.Execute(@"INSERT INTO [Songs] ([Name], [PublishedDate], [ArtistId]) VALUES (@Name, @PublishedDate, @ArtistId)",
new
{
Name = name,
PublishedDate = publishedDate,
ArtistId = artistId
});
}
It's kind of becoming obvious at this point. Barely any difference between this piece of code and the one with the WHERE
clause. Everything revolves around writing the query in SQL and sending in some parameters. Joins are a bit trickier but easy enough to be learned within a day. In contrast, Entity Framework has a much steeper learning curve.
Another plus of Dapper is that you don't have to completely abandon Entity Framework in order to use it. For example, I still use EF for its Identity providers because I'm not really keen on writing custom implementations for them. You can also continuously replace Entity Framework with Dapper in your application query-by-query without too much hassle, especially if you had the foresight to use repositories.
In a nutshell, both are great tools. It all depends on what you're striving for when developing. Personally, I use Entity Framework for Identity and Dapper everywhere else and I feel like I've found the golden mean.