Developers choose Entity framework ORM (EF) for better productivity when accessing the database. But, when the product is built that went from bare bones to very complex and heavy data access then comes the performance.
Sometimes its the Entity framework that kills the performance so the choice when searching for a better ORM than Entity framework is Dapper.
In this post, I’ll walk you through how we can replace the existing entity framework code with dapper.
Here are our entity model classes for a simple Todo application.
public class ToDoItem { public ToDoItem() { Details = new HashSet<ToDoItemDetails>(); } [Key] public int Id { get; set; } public string ToDoText { get; set; } public bool IsCompleted { get; set; } public int Priority { get; set; } public ICollection<ToDoItemDetails> Details { get; set; } } public class ToDoItemDetails { [Key] public int Id { get; set; } public int TodoItemId { get; set; } public string Notes { get; set; } public DateTime CreatedDate { get; set; } public ToDoItem TodoItem { get; set; } }
And here is our method to retrieve all todo items and its details using entity framework.
public IEnumerable GetAll() { return _context.TodoItem.Include(a => a.Details).ToList(); }
The above code looks so minimal and maintainable. Let’s see how the same thing can be done with Dapper.
For the purpose of the article, I’m making use of the entity models that are created for entity framework. In real time, we’d have to use the DTO or a simple view model to return the data from the repository.
//accessing with Dapper
public IDbConnection Connection { get { return new SqlConnection(_configuration.GetConnectionString(“MyConnectionString”)); } } public IEnumerable GetAll() { var todoDictionary = new Dictionary<int, ToDoItem>(); string query = “SELECT * FROM ToDoItems td JOIN TodoItemDetails details ON details.TodoItemId = td.Id”; using (IDbConnection con = Connection) { var result = con.Query<ToDoItem, ToDoItemDetails, ToDoItem>(query, (todoItem, todoItemDetail) => { ToDoItem todoEntry; if(!todoDictionary.TryGetValue(todoItem.Id, out todoEntry)) { todoEntry = todoItem; todoEntry.Details = new List(); todoDictionary.Add(todoEntry.Id, todoEntry); } todoEntry.Details.Add(todoItemDetail); return todoEntry; }); return result; } }
The above code is a bit complex as we are dealing with multiple tables and we have to fill the details list object in the TodoItem class.
As you can see we have more work to do with Dapper. But, there isn’t anything special except that it looks like the ADO.NET style of having the query into a string and supplying arguments to the Query method to get the appropriate result which can be mapped to ToDoItem class.
When modifying applications like the above one, it’s better to have an interface like repositories and when you implement these repositories you do it separately for entity framework access and separate for Dapper.
I recommend implementing a repository interface in a separate class for a specific ORM.
We already have EF in the repository implementation. If we want to have a method specific implementation as in our example GetAll() method is replaced with the existing EF code. Instead, it’s better to have a separate class for Dapper implementations. When you want to have the dapper implementation, call the dapper specific method in that class.
As you can see we have removed the existing entity framework code with Dapper code for better performance. I have other methods in the repository that make use of entity framework for reading and writing to the database.
Writing code in LINQ to SQL is more productive than writing in Dapper. But, when it comes to performance dapper wins over entity framework.
We can have both LINQ to SQL and entity framework code in the same class to access the database. But, this is not a good design consideration as we may be switching to a better performing ORM tomorrow.
Karthik is a passionate Full Stack developer working primarily on .NET Core, microservices, distributed systems, VUE and JavaScript. He also loves NBA basketball so you might find some NBA examples in his posts and he owns this blog.
In this post, we’ll see how to test gRPC Server applications using different clients. And… Read More
In this post, we'll create a new gRPC project in ASP.NET Core and see what's… Read More
In this blog post, we’ll see how to run dotnet core projects without opening visual… Read More
Programmatically evaluating policies is useful when we want to provide access or hide some data… Read More
We saw how we could set up policy-based authorization in our previous article. In this… Read More
What is policy-based authorization and how to set up policy-based authorization with handlers and policies… Read More
This website uses cookies.