entity-frameworkdapperquery-performance

How to efficiently migrate EF linq queries to Dapper?


I'm trying to migration EF to Dapper and I'm looking for a better and efficient way on how to migrate existing linq expressions "IQueryable" to use Dapper.

Ex:

public class MyDbContext : DbContext
{
    public DbSet<MyEntity> MyEntity { get; set; }
    +20 more entities..
}

// Inside repository
using (var context = new MyDbContext())
{
     context.MyEntity.Where( x => x.Id == 1) // How can I easily migrate this linq to Dapper?
}

The above code is a simple example only of what I'm trying to migrate. Some of those queries are mix of simple and complex. Currently, I have 20+ repositories and 20+ DbSet in MyDbContext that used that kind of approach inside repositories.

I searched in the internet and I haven't found a better approach. So far the only way to do this is to convert linq into query string one by one and use it in Dapper. It is doable but tedious and huge effort. Performance is my biggest concern why I'am migrating to Dapper.

Does anyone has a better way to do this than what I'm currently thinking?


Solution

  • I found a medicine to my own problem. Instead of intercepting the query, I allow to pass the predicate and create Linq like function same with existing.

    public class QueryLinq
    {
        private readonly IDatabase _database;
    
        public QueryLinq(IDatabase database)
        {
            _database = database; // Dapper implementation
        }
       
        public IEnumerable<T> Where<T>(Func<T,bool> predicate)
        {
            var enumerable = _database.Query<T>();
            return enumerable(predicate);
        }
    }
    
    // Existing Repository
    public class MyRepository
    {
        private readonly QueryLinq _queryLinq;
    
        public MyRepository(QueryLinq queryLinq)
        {
           _queryLinq = queryLinq;
        }
       
        public IEnumerable<MyEntity> SelectMyEntity()
        {
            // Before
            // using (var context = new MyDbContext())
            // {            
            //    context.MyEntity.Where( x => x.Id == 1);
            // }
    
            // Now
            return _queryLinq.Where<MyEntity>( x => x.Id == 1);
        }
    }
    

    In this approach, I don't need to worry about existing queries.

    Update 8/16/2018: for the complete details of this approach kindly visit here.