How to map to a Dictionary object from database results using Dapper Dot Net?

旧街凉风 提交于 2019-11-27 10:14:40

问题


If I have a simple query such as:

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

and I want to map it to a dictionary object such as:

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

How would I do this with Dapper?

I assume it is something like:

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

But can't figure out the proper syntax.


回答1:


There's various ways already shown; personally I'd just use the non-generic api:

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



回答2:


Works also without an additional class:

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

NOTE: When using Dapper.NET 3.5 version, the Query method that takes the first, second and return types requires you specify more parameters, as the .NET 4.0 and .NET 4.5 versions take advantage of optional arguments.

In this case, the following code should work:

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

Most of the arguments will revert to a default, but splitOn is required, as it will otherwise default to a value of 'id'.

For a query that returns two columns, 'ID' and 'Description', splitOn should be set to 'Description'.




回答3:


string strSql = "SELECT DISTINCT TableID AS [Key],TableName AS [Value] FROM dbo.TS_TStuctMaster";
Dictionary<string,string> dicts = sqlConnection.Query<KeyValuePair<string,string>>(strSql).ToDictionary(pair => pair.Key, pair => pair.Value);

You can use aliases and strong types.

Aliases are the key points, which match the attributes of KeyValuePair type Key and Value.

It works under strong typing and runs well.

I don't like dynamic type. It brings disaster in certain situations. Moreover, the boxing and unboxing brings performance loss.




回答4:


I'm not sure if what you're trying to do is possible. If you define a class to map the query to this becomes far more trivial:

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

Then, you would just do this:

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



回答5:


Dapper also has an extension method for ExecuteReader. So, you could also do this:

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

This approach works without knowing the column names. Moreover, if you don't know the data types, you could change Dictionary<string,int> to Dictionary<string,object> and GetInt32(i) to GetValue(i).




回答6:


If you are using > .net 4.7 or netstandard2 you can use value tuples. the code is nice and terse and there is no use of dynamics.

var sql = "SELECT UniqueString, Id  FROM Table";
var dict = conn.Query<(string UniqueString, int Id)>(sql)
           .ToDictionary(t => t.UniqueString,t => t.Id);


来源:https://stackoverflow.com/questions/14780767/how-to-map-to-a-dictionary-object-from-database-results-using-dapper-dot-net

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!