Como criar argumentos para uma consulta Dapper dinamicamente

86

Eu tenho um dicionário de valores. Ex: "Nome": "Alex"

Existe uma maneira de passar isso para Dapper como argumentos para uma consulta?

Aqui está um exemplo que mostra o que eu quero fazer.

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

Respostas:

140

Sim:

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

Em seguida, passe dbArgsno lugar de args:

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

Alternativamente, você pode escrever sua própria classe que implemente IDynamicParameters.

Observe que se você estiver começando a partir de um objeto (a abordagem usual com dapper), você também pode usar este modelo com DynamicParameterscomo ponto de partida:

var dbArgs = new DynamicParameters(templateObject);
Marc Gravell
fonte
25
Observe que você pode fazer new DynamicParameters(dictionary)isso e funcionará perfeitamente.
asgerhallas
1
@asgerhallas isso pode não ter sido verdade em fevereiro, mas sim: você está certo - isso certamente é verdade agora
Marc Gravell
10
para que os novos DynamicParameters (dicionário) funcionem, o dicionário deve ser um IEnumerable <KeyValuePair <string, object >>, por exemplo, Dictionary <string, object>. O dicionário <string, string> não funcionou.
Zar Shardan
17

Eu sei que essa é uma pergunta antiga (tipo, 5 anos), mas eu estava lutando contra a mesma coisa. A resposta completa está nos comentários para a outra resposta, mas pensei em oferecer um exemplo completo aqui.

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));

Ou, para ser totalmente dinâmico, você pode criar um método como este, que aceitará qualquer modelo, qualquer consulta e qualquer 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;
    }

E então, para chamar este método:

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

EDITAR LONGO DEPOIS

Essa resposta continua recebendo votos positivos, então, aparentemente, ainda é uma necessidade. Peguei essa solução e criei um pacote NuGet de acesso a dados inteiro baseado no Dapper. Ele reduz suas operações de CRUD e consulta a uma única linha de código.

Aqui está o pacote NuGet .

Casey Crookston
fonte
0

Também é possível usar um ExpandoObjectcomo os parâmetros de uma consulta, em vez da classe específica do 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
fonte