Domanda Come mappare un oggetto dizionario dai risultati del database usando Dapper Dot Net?


Se ho una query semplice come:

string sql = "SELECT UniqueString, ID  FROM Table";

e voglio mapparlo ad un oggetto dizionario come:

Dictionary<string, int> myDictionary = new Dictionary<string, int>();      

Come lo farei con Dapper?

Presumo che sia qualcosa del tipo:

myDictionary = conn.Query<string, int>(sql, new {  }).ToDictionary();

Ma non riesco a capire la sintassi corretta.


44
2018-02-08 20:25


origine


risposte:


Ci sono vari modi già mostrati; personalmente userò semplicemente l'API non generica:

var dict = conn.Query(sql, args).ToDictionary(
    row => (string)row.UniqueString,
    row => (int)row.Id);

79
2018-02-09 08:37



Funziona anche senza una classe aggiuntiva:

var myDictionary = conn.Query<string, int, KeyValuePair<string,int>>(sql, (s,i) => new KeyValuePair<string, int>(s,i))
    .ToDictionary(kv => kv.Key, kv => kv.Value);

NOTA: Quando si utilizza la versione Dapper.NET 3.5, il metodo Query che accetta il primo, il secondo e il tipo restituito richiede di specificare più parametri, poiché le versioni .NET 4.0 e .NET 4.5 sfruttano argomenti opzionali.

In questo caso, il seguente codice dovrebbe funzionare:

string splitOn = "TheNameOfTheValueColumn";
var myDictionary = conn.Query<string, int, KeyValuePair<string,int>>(sql, (s,i) => new KeyValuePair<string, int>(s,i), null, null, false, splitOn, null, null)
        .ToDictionary(kv => kv.Key, kv => kv.Value);

La maggior parte degli argomenti tornerà a un valore predefinito, ma splitOn è richiesto, poiché altrimenti verrà impostato automaticamente su un valore di 'id'.

Per una query che restituisce due colonne, 'ID' e 'Descrizione', splitOn dovrebbe essere impostato suDescrizione'.


16
2018-02-08 21:56



Non sono sicuro se ciò che stai cercando di fare sia possibile. Se si definisce una classe per mappare la query, diventa molto più semplice:

public class MyRow
{
    public int Id { get; set; }
    public string UniqueString { get; set; }
}

Quindi, dovresti solo fare questo:

var sql = "SELECT UniqueString, ID  FROM Table";
var myDictionary = conn.Query<MyRow>(sql).ToDictionary(row => row.UniqueString, row => row.Id);

6
2018-02-08 21:15



Dapper ha anche un metodo di estensione per ExecuteReader. Quindi, potresti anche fare questo:

var sql = "SELECT UniqueString, ID  FROM Table";
var rows = new List<Dictionary<string, int>>();
using (var reader = cn.ExecuteReader(sql)) {
    while (reader.Read()) {
        var dict = new Dictionary<string, int>();
        for (var i = 0; i < reader.FieldCount; i++) {
            dict[reader.GetName(i)] = reader.GetInt32(i);
        }
        rows.Add(dict);
    }
}

Questo approccio funziona senza conoscere i nomi delle colonne. Inoltre, se non conosci i tipi di dati, potresti cambiare Dictionary<string,int> a Dictionary<string,object> e GetInt32(i) a GetValue(i).


6
2017-11-19 18:35