95 votes

Comment créer dynamiquement les arguments d'une requête Dapper ?

J'ai un dictionnaire de valeurs Eg "Nom" : "Alex"

Existe-t-il un moyen de passer cela à Dapper comme arguments pour une requête ?

Voici un exemple montrant ce que je veux faire.

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

157voto

Marc Gravell Points 482669

Oui :

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

Puis passer dbArgs à la place de args :

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

Alternativement, vous pouvez écrire votre propre classe qui implémente IDynamicParameters .

Notez que si vous partez d'un objet (l'approche habituelle avec dapper), vous pouvez aussi utiliser ce modèle avec DynamicParameters comme point de départ :

var dbArgs = new DynamicParameters(templateObject);

29 votes

Notez que vous pouvez faire new DynamicParameters(dictionary) et ça marchera très bien.

1 votes

@asgerhallas ce n'était peut-être pas vrai en février, mais oui : vous avez raison, c'est certainement vrai maintenant.

13 votes

Pour que new DynamicParameters(dictionary) fonctionne, dictionary doit être un IEnumerable<KeyValuePair<string, object>>, par exemple Dictionary<string, object>. Dictionary<string,string> ne fonctionne pas.

19voto

Casey Crookston Points 10352

Je sais qu'il s'agit d'une vieille question (vieille de 5 ans), mais je me débattais avec la même chose. La réponse complète se trouve dans les commentaires de l'autre réponse, mais j'ai pensé que je pourrais offrir un exemple complet ici.

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, pour être totalement dynamique, vous pouvez créer une méthode comme celle-ci, qui prendra n'importe quel modèle, n'importe quelle requête et n'importe quel ensemble de paramètres de requête :

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

Et ensuite pour appeler cette méthode :

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

ÉDITER LONGTEMPS APRÈS

Cette réponse continue d'obtenir des votes positifs, donc il semble que ce soit encore un besoin. J'ai pris cette solution et j'ai créé un paquet NuGet complet d'accès aux données construit au-dessus de Dapper. Il réduit vos opérations CRUD et de requête à une seule ligne de code.

Voici le Paquet NuGet .

2voto

turdus-merula Points 4230

On peut aussi utiliser un ExpandoObject comme paramètres d'une requête, au lieu de la classe spécifique à 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);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X