asp.net 如何使用Dapper Dot Net从数据库结果Map到Dictionary对象?

alen0pnh  于 2023-03-13  发布在  .NET
关注(0)|答案(8)|浏览(150)

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

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

我想把它Map到一个dictionary对象,比如

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

我该怎么和戴普做呢?
我想大概是这样的:

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

但却不知道正确的语法。

rqenqsqc

rqenqsqc1#

我们已经展示了很多种方法我个人会使用非通用的API:

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

blpfk2vs2#

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

可以使用别名和强类型。

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

它在强类型下工作,运行良好。

  • 我不喜欢动态类型。在某些情况下会带来灾难。此外,装箱和解箱会带来性能损失。*
gmxoilav

gmxoilav3#

也可以在没有其他类的情况下工作:

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

注意:使用Dapper.NET 3.5版本时,接受第一个、第二个和返回类型的Query方法需要您指定更多参数,因为.NET 4.0和.NET 4.5版本利用optional arguments

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

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

大多数参数将恢复为默认值,但splitOn是必需的,否则它将默认为'id'值。
对于返回两列“ID”和“*Description *”的查询,splitOn应设置为“*Description *”。

abithluo

abithluo4#

如果你使用的是〉.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);
6psbrbz9

6psbrbz95#

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

这种方法不需要知道列名,而且,如果不知道数据类型,可以将Dictionary<string,int>更改为Dictionary<string,object>,将GetInt32(i)更改为GetValue(i)

6l7fqoea

6l7fqoea6#

我不确定你尝试做的事情是否可行,如果你定义一个类来Map查询,这就变得微不足道了:

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

然后,您只需执行以下操作:

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

zzoitvuj7#

对于在运行时不知道其结构的表

using var db = new SqlConnection(_connectionString);
    var sql = $"Select * From {tableName} Order By {primaryKey}";

    var result = await db.QueryAsync(sql); 
    return result
        .Cast<IDictionary<string, object>>()
        .Select(it => it.ToDictionary(it => it.Key, it => it.Value));
tag5nh1u

tag5nh1u8#

我个人更喜欢这样使用(1班轮):

var dict = dapper.Query<(string, int)>(sql).ToDictionary(x => x.Item1, row => row.Item2);

相关问题