Entity Framework

Replacing existing entity framework code with Dapper

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.

Entity models and accessing data with Entity framework

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.

Accessing data 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.

Design considerations

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.

Conclusion

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.

Disqus Comments Loading...
Share
Published by
Karthik Chintala
Tags: dapperlinq

Recent Posts

2 Good Tools To Test gRPC Server Applications

In this post, we’ll see how to test gRPC Server applications using different clients. And… Read More

2 years ago

Exploring gRPC project in ASP.NET Core

In this post, we'll create a new gRPC project in ASP.NET Core and see what's… Read More

2 years ago

Run dotnet core projects without opening visual studio

In this blog post, we’ll see how to run dotnet core projects without opening visual… Read More

2 years ago

Programmatically evaluating policies in ASP.NET Core

Programmatically evaluating policies is useful when we want to provide access or hide some data… Read More

2 years ago

Multiple authorization handlers for the same requirement in ASP.NET Core

We saw how we could set up policy-based authorization in our previous article. In this… Read More

2 years ago

Policy-Based Authorization in ASP.NET Core

What is policy-based authorization and how to set up policy-based authorization with handlers and policies… Read More

2 years ago

This website uses cookies.