Cómo crear argumentos para una consulta Dapper de forma dinámica

86

Tengo un diccionario de valores Ej. "Nombre": "Alex"

¿Hay alguna forma de pasar esto a Dapper como argumentos para una consulta?

Aquí hay un ejemplo que muestra lo que quiero hacer.

IDictionary<string, string> args = GetArgsFromSomewhere();
string query = "select * from people where Name = @Name";
var stuff = connection.Query<ExtractionRecord>(query, args);
Cogslave
fuente

Respuestas:

140

Si:

var dbArgs = new DynamicParameters();
foreach(var pair in args) dbArgs.Add(pair.Key, pair.Value);

Luego pase dbArgsen lugar de args:

var stuff = connection.Query<ExtractionRecord>(query, dbArgs);

Alternativamente, puede escribir su propia clase que implemente IDynamicParameters.

Tenga en cuenta que si está comenzando desde un objeto (el enfoque habitual con dapper), también puede usar esta plantilla con DynamicParameterscomo punto de partida:

var dbArgs = new DynamicParameters(templateObject);
Marc Gravell
fuente
25
Tenga en cuenta que puede hacerlo new DynamicParameters(dictionary)y funcionará bien.
asgerhallas
1
@asgerhallas eso podría no haber sido cierto en febrero, pero sí: tienes razón, eso es ciertamente cierto ahora
Marc Gravell
10
Para que los nuevos DynamicParameters (diccionario) funcionen, el diccionario debe ser un IEnumerable <KeyValuePair <string, object >>, por ejemplo Dictionary <string, object>. El diccionario <cadena, cadena> no funcionó.
Zar Shardan
17

Sé que esta es una pregunta antigua (como 5 años) pero estaba luchando con lo mismo. La respuesta completa está en los comentarios a la otra respuesta, pero pensé que ofrecería un ejemplo completo aquí.

string query = "SELECT * FROM MyTableName WHERE Foo = @Foo AND Bar = @Bar";

Dictionary<string, object> dictionary = new Dictionary<string, object>();
dictionary.Add("@Foo", "foo");
dictionary.Add("@Bar", "bar");

var results = connection.Query<MyTableName>(query, new DynamicParameters(dictionary));

O, para ser completamente dinámico, puede crear un método como este, que tomará cualquier modelo, cualquier consulta y cualquier conjunto de parámetros de consulta:

    public static IEnumerable<T> Get<T>(string query, Dictionary<string, object> dictionary)
    {
        IEnumerable<T> entities = connection.Query<T>(query, new DynamicParameters(dictionary));
        return entities;
    }

Y luego para llamar a este método:

var results = Get<MyTable>(query, dictionary)

EDITAR MUCHO DESPUÉS

Esta respuesta continúa recibiendo votos positivos, por lo que aparentemente sigue siendo una necesidad. Tomé esta solución y creé un paquete NuGet completo de acceso a datos construido sobre Dapper. Reduce sus operaciones CRUD y de consulta a una sola línea de código.

Aquí está el paquete NuGet .

Casey Crookston
fuente
0

También se puede usar an ExpandoObjectcomo parámetros de una consulta, en lugar de la clase específica de Dapper DynamicParameters:

ExpandoObject param = new ExpandoObject();

IDictionary<string, object> paramAsDict = param as IDictionary<string, object>;
paramAsDict.Add("foo", 42);
paramAsDict.Add("bar", "test");

MyRecord stuff = connection.Query<MyRecord>(query, param);
turdus-merula
fuente