如何使用Dapper Dot Net从数据库结果映射到Dictionary对象?

jps*_*ook 55 c# asp.net dapper

如果我有一个简单的查询,例如:

string sql = "SELECT UniqueString, ID  FROM Table";
Run Code Online (Sandbox Code Playgroud)

我想将它映射到字典对象,例如:

Dictionary<string, int> myDictionary = new Dictionary<string, int>();      
Run Code Online (Sandbox Code Playgroud)

我怎么用Dapper这样做?

我假设它是这样的:

myDictionary = conn.Query<string, int>(sql, new {  }).ToDictionary();
Run Code Online (Sandbox Code Playgroud)

但无法弄清楚正确的语法.

Mar*_*ell 102

已经有各种各样的方式; 我个人只是使​​用非通用api:

var dict = conn.Query(sql, args).ToDictionary(
    row => (string)row.UniqueString,
    row => (int)row.Id);
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考.返回的字段的属性名称区分大小写.在Oracle中,返回给我的字段都是大写字母,例如row.UniqueString从Oracle返回为row.UNIQUESTRING. (3认同)
  • @Colin,因为其他RDBMS允许区分大小写的名称(所以.foo,.FOO和.Foo都不同)我不确定我能做多少,除了说"期待你的RDBMS返回" (3认同)
  • 我什至没有意识到您可以在查询方法中省略返回类型。 (2认同)

Tim*_*ter 19

也没有额外的课程:

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);
Run Code Online (Sandbox Code Playgroud)

注意:使用Dapper.NET 3.5版本时,采用第一种,第二种和返回类型的Query方法需要指定更多参数,因为.NET 4.0和.NET 4.5版本利用了可选参数.

在这种情况下,以下代码应该工作:

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);
Run Code Online (Sandbox Code Playgroud)

大多数参数将恢复为默认值,但是splitOn是必需的,否则默认值为"id".

对于返回两列的查询," ID "和" 描述 " splitOn应设置为" 描述 ".


小智 14

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);
Run Code Online (Sandbox Code Playgroud)

您可以使用别名和强类型.

别名是关键点,它与KeyValuePair类型Key和Value的属性相匹配.

它在强类型下运行并且运行良好.

我不喜欢动态类型.它在某些情况下会带来灾难.而且,装箱和拆箱会带来性能损失.


w.b*_*ian 7

我不确定你想做什么是可能的.如果你定义一个类来将查询映射到这个变得更加微不足道:

public class MyRow
{
    public int Id { get; set; }
    public string UniqueString { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后,你会这样做:

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


dal*_*man 6

Dapper也有一个扩展方法ExecuteReader.所以,你也可以这样做:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

此方法在不知道列名称的情况下工作.此外,如果你不知道的数据类型,你可以改变Dictionary<string,int>Dictionary<string,object>GetInt32(i)GetValue(i).


her*_*ist 5

如果使用> .net 4.7或netstandard2,则可以使用值元组。该代码简洁明了,没有使用动态特性。

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