¿Cómo migrar eficientemente las consultas de EF linq a Dapper?

dapper entity-framework query-performance

Pregunta

Estoy intentando migrar EF a Dapper y estoy buscando una forma mejor y más eficiente de cómo migrar expresiones linq existentes "IQueryable" para usar 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?
}

El código anterior es un simple ejemplo solo de lo que estoy tratando de migrar. Algunas de esas consultas son mixtas de simples y complejas. Actualmente, tengo más de 20 repositorios y más de 20 DbSet en MyDbContext que utilizan ese tipo de enfoque dentro de los repositorios.

Busqué en internet y no encontré un mejor enfoque. Hasta ahora, la única forma de hacerlo es convertir linq en cadena de consulta uno por uno y usarla en Dapper. Es factible pero tedioso y enorme esfuerzo. El rendimiento es mi mayor preocupación por qué estoy migrando a Dapper.

¿Alguien tiene una mejor manera de hacer esto de lo que estoy pensando actualmente?

Respuesta aceptada

Encontré un medicamento para mi propio problema. En lugar de interceptar la consulta, permito pasar el predicado y crear Linq como función igual que existente.

public class QueryLinq
{
    private readonly IDatabase _database;
    public QueryLinq(IDatabase database)
    {
        _database = database; // Dapper implementation
    }

    public IEnumberable<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);
    }
}

En este enfoque, no necesito preocuparme por las consultas existentes.

Actualización 16/08/2018: para obtener todos los detalles de este enfoque, visite amablemente aquí .


Respuesta popular

Puede usar Entity Framework Logging para generar el SQL generado en la consola de Visual Studio. Es tan simple como agregar:

_context.Database.Log = x => Trace.WriteLine(x);

a su servicio o clase (s) de repositorio.

Estoy haciendo exactamente lo que estás haciendo, y por la misma razón. Verá que el SQL que LINQ genera puede ser subóptimo, por lo que copiar directamente el mismo SQL subóptimo para que Dapper lo use me pareció un ejercicio sin sentido.

Lo que he hecho es identificar las consultas LINQ que realizan lo peor y volver a escribirlas en SQL, desde cero, para usar con Dapper. Con lo que he terminado es una combinación de LINQ y Dapper en todo el sistema, que se beneficia de la solidez de ambos enfoques, es decir, el rápido desarrollo de LINQ y las mejoras en el rendimiento de Dapper y las consultas SQL optimizadas.



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué