Jak dynamicznie tworzyć argumenty dla zapytania Dapper

86

Mam słownik wartości Np. „Nazwa”: „Alex”

Czy istnieje sposób, aby przekazać to Dapperowi jako argumenty zapytania?

Oto przykład pokazujący, co chcę zrobić.

IDictionary<string, string> args = GetArgsFromSomewhere();
string query = "select * from people where Name = @Name";
var stuff = connection.Query<ExtractionRecord>(query, args);
Cogslave
źródło

Odpowiedzi:

140

Tak:

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

Następnie przekaż dbArgsw miejsce args:

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

Alternatywnie możesz napisać własną klasę, która implementuje IDynamicParameters.

Zwróć uwagę, że jeśli zaczynasz od obiektu (typowe podejście z dapper), możesz również użyć tego szablonu DynamicParametersjako punktu wyjścia:

var dbArgs = new DynamicParameters(templateObject);
Marc Gravell
źródło
25
Pamiętaj, że możesz to zrobić new DynamicParameters(dictionary)i będzie działać dobrze.
asgerhallas
1
@asgerhallas, co mogło nie być prawdą w lutym, ale tak: masz rację - to z pewnością prawda teraz
Marc Gravell
10
aby nowy DynamicParameters (słownik) działał, słownik musi być IEnumerable <KeyValuePair <string, object >>, na przykład Dictionary <string, object>. Słownik <string, string> nie działał.
Zar Shardan
17

Wiem, że to stare pytanie (jakieś 5 lat), ale walczyłem z tym samym. Pełna odpowiedź znajduje się w komentarzach do drugiej odpowiedzi, ale pomyślałem, że podam tutaj pełny przykład.

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

Lub, aby być w pełni dynamicznym, możesz utworzyć taką metodę, która będzie przyjmować dowolny model, dowolne zapytanie i dowolny zestaw parametrów zapytania:

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

A następnie wywołanie tej metody:

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

EDYTUJ DŁUGO PO

Ta odpowiedź wciąż zyskuje na popularności, więc najwyraźniej nadal jest potrzebna. Wziąłem to rozwiązanie i utworzyłem cały pakiet NuGet dostępu do danych zbudowany na bazie Dapper. Redukuje operacje CRUD i zapytań do jednej linii kodu.

Oto pakiet NuGet .

Casey Crookston
źródło
0

Można również użyć ExpandoObjectjako parametru zapytania zamiast klasy specyficznej dla Dappera 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
źródło