【问题标题】:Is there a way retrieve each row as IDictionary<string, string> using Dapper?有没有办法使用 Dapper 将每一行检索为 IDictionary<string, string> ?
【发布时间】:2016-08-27 22:51:31
【问题描述】:

我有一个这样的表结构:

表 tbUser

--ID (int)

--名称(varchar)

--生日(日期时间)

--评分(双)

什么时候

"SELECT * FROM tbUser"

我希望查询结果中的每一行看起来像(将每一列转换为字符串格式):

row["ID"] = "1";
row["Name"] "John"
row["Birthday"] = "1980-01-01"
row["rating"] = "3.4"

我需要字符串的原因是它们易于操作/格式化/显示并且有时更安全(如果另一位工程师更改了 DB 中的列类型——例如“评级”列从 double 更改为 int,该程序不太可能抛出异常,因为它只关心字符串)

我知道有一种方法可以将 DapperRow 转换为 IDictionary&lt;string, object&gt;,它非常接近 IDictionary&lt;string, string&gt;

var result = conn.Query("SELECT * FROM tbUser");
foreach (IDictionary<string, object> row in result) {
  // I have to write my own object->string conversion in every loop
}

非常感谢任何建议!

【问题讨论】:

  • 你能不能只创建自己的类并解析返回的结果。完全控制返回的内容?
  • If another engineer changed column type in DB --e.g. "rating" column changed from double to int, the program is less likely throw exception as it only cares about strings 只是让你知道 - 这是可怕的想法。这只会隐藏问题并使其无法调试。你想要努力失败并快速失败。您不想将值视为某种是但不是的。如果工程师更改了列的类型,则意味着原始代码错误,因此也应根据类型更改进行更新。

标签: c# .net string dictionary dapper


【解决方案1】:

不,Dapper 不会为您这样做(也不应该这样做!)。首先 - 转换是在数据库中完成,还是在代码中完成?以及如何格式化? (我们如何格式化 2,000.20?并非所有文化都使用 . 作为小数位,也不是 , 作为千位分隔符。日期更糟)。

不过,你可以这样写:

var data = Connection.Query("SELECT TOP 100 * FROM People") 
                      as IEnumerable<IDictionary<string, object>>;

var outData = data.Select(r => r.ToDictionary(d => d.Key, d => d.Value?.ToString()));

或者您可以编写自己的扩展:

public static class DapperExtensions
{
    public static IEnumerable<IDictionary<string, string>> QueryDictionary(this IDbConnection connection, string query)
    {
        var data = Dapper.SqlMapper.Query(connection, query) as IEnumerable<IDictionary<string, object>>;
        return data.Select(r => r.ToDictionary(d => d.Key, d => d.Value?.ToString()));
    }
}

然后这样使用它:

var data = Connection.QueryDictionary("SELECT TOP 100 * FROM People");

【讨论】:

    【解决方案2】:

    这似乎已经得到了回答。

    您需要创建一个模型/类,然后按照此代码 sn-p 来实现您想要的;

    Dictionary<string, SP> dictionary = connection.Query<SP>(@"
    SELECT 
         routine_name AS RoutineName,
         created AS Created,
         modified AS Modified
    FROM PROCEDURES
    ").ToDictionary(m => m.RoutineName, m => m);
    

    完整答案请参见此主题 - How to put objects into a dictionary using Dapper in C#?

    【讨论】:

    • 这是一个完全不同的问题。不过,如果解决方案与链接答案中所写的完全一样,您应该投票以重复关闭,而不是在此处发布相同的答案
    • 这是要使用的,也是创建自己的模型/类以使用的示例-不是确切的答案。不应该帮助指出正确的方向吗?
    • 是的,我明白 - 我不是在攻击你,只是在下次给你小费。如果通过上述方法解决了问题,那将是直接重复的(即使模型不同)。通常重复的答案实际上是有害的,因为它会影响 SEO 和搜索结果的排名。
    • @Rob 啊,这是有道理的。 :) 感谢您的建议。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-24
    • 1970-01-01
    相关资源
    最近更新 更多