Dapper fuertemente tipificado colección de Tipo

c# dapper

Pregunta

En mi aplicación, uso Dapper para acceder a la base de datos.

Tengo el siguiente código de ejemplo:

public IEnumerable GetByParentId(Type childType, string table) 
{
    IDbConnection _connection = _dbProvider.GetConnection();

    var _sqlString = "select * from " + table;

    IEnumerable _ret = _connection.Query(_sqlString).ToList(); 
    //return IEnumerable<Dapper.SqlMapper.FastExpando> 

    return _ret;
}

¿Es posible lanzar el elemento FastExpando a mi childType o forzar a Dapper a devolver una colección fuertemente tipada?

No puedo cambiar la firma de mi método!

Respuesta aceptada

Puede llamar al método Query a través de la reflexión y proporcionar un argumento TItem genérico de su tipo de hijo. Entonces, Dapper devolverá IEnumerable y podrás lanzarlo. Además, puede bifurcar Dapper (no es muy grande) y hacer una sobrecarga muy simple de Query, que incluirá el argumento (Type childType) y llamará a los métodos adecuados dentro.

Lo que enfrenta es el problema de C # en el trabajo con medicamentos genéricos. Al ser un lenguaje estáticamente tipado, C # funciona mal con tipos dinámicos. Si quieres trabajar dinámicamente, siempre terminas reflejado.

Aquí hay una muestra de cómo se puede llamar al método de consulta con argumentos de tipo. Puede que tenga que corregir esto un poco:

    public IEnumerable GetByParentId(Type childType, string table)
    {
        IDbConnection _connection = _dbProvider.GetConnection();

        var _sqlString = "select * from " + table;

        var t = typeof(SqlMapper);
        var genericQuery = t.GetMethods().Where(x => x.Name == "Query" && x.GetGenericArguments().Length == 1).First(); // You can cache this object.
        var concreteQuery = genericQuery.MakeGenericMethod(childType); // you can also keep a dictionary of these, for speed.
        var _ret = (IEnumerable)concreteQuery.Invoke(null, new object[] { _connection, _sqlString });

        return _ret;
    }

Adjuntar:

Además, veo un problema de diseño más general aquí. Desea especificar el tipo de forma dinámica, pero luego desea obtener objetos estáticamente tipados, que podrá lanzar (supongo que estático, o desea continuar con la reflexión?). Entonces ... ¿Por qué creas una interfaz dinámica en primer lugar? Usted dice que no puede cambiar la interfaz, pero parece un poco estúpido. Parece que todo su contexto está tipado estáticamente, pero luego, por alguna razón, tiene un método de tipo dinámico. Si conoce tipos durante el tiempo de compilación (o mediante argumentos genéricos en el tiempo de ejecución), entonces simplemente debe cambiar su método a algo como esto:

    public IEnumerable<T> GetByParentId<T>(string table)
    {
        IDbConnection _connection = _dbProvider.GetConnection();
        var _sqlString = "select * from " + table;
        var _ret = _connection.Query<T>(_sqlString);
        return _ret;
    }


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é