【问题标题】:Retrieving data from a database through SqlDataReader and converting it to JSON通过 SqlDataReader 从数据库中检索数据并将其转换为 JSON
【发布时间】:2015-10-31 10:00:36
【问题描述】:

我想将我检索到的数据转换成JSON;我正在使用SqlDataReader 进行检索。为此,我需要将我的数据存储到var。 我收到此错误:

“System.Reflection.AmbiguousMatchException”类型的异常发生在 mscorlib.dll 中,但未在用户代码中处理

附加信息:找到不明确的匹配项。

在以下代码中:

public string GetDetails(int Id)
{   
    var jsonDoc = "";

    string con = "server=FACULTY01\\SQLSERVER2012ENT; database=SampleDb; uid=sa; pwd=sa9";
    SqlConnection scon = new SqlConnection(con);
    string qry = "Select * from Information where ID =" + Id;
    SqlCommand cmd = new SqlCommand(qry, scon);
    scon.Open();
    SqlDataReader rdr = cmd.ExecuteReader();
    var details = rdr;
    
    JavaScriptSerializer jss = new JavaScriptSerializer();
    jsonDoc = jss.Serialize(details);
    scon.Close();
    return jsonDoc;
}

【问题讨论】:

  • 请显示完整堆栈跟踪。顺便说一句:1)你应该使用using语句; 2) 你应该使用参数化 SQL。
  • @JonSkeet 亲爱的,我正在使用它,没有更多代码
  • 或任何其他方法将reader 存储到var 中?我只是想将重试数据存储到var 以进行 JSON 序列化。
  • 没有更多的代码并不意味着没有更多的堆栈跟踪。目前尚不清楚您的代码是否正在执行 - 也许这实际上是一个路由问题? (不清楚为什么你有一个details 变量,而不仅仅是调用jss.Serialize(rdr); - 这不像使用使用var 声明的变量会改变任何东西。

标签: c# asp.net json serialization sqldatareader


【解决方案1】:

您不能直接序列化 SqlDataReader 并期望输出包含来自 SQL 查询的数据。这不是SqlDataReader 的工作方式。 SqlDataReader 是一种从 SQL 结果中检索数据的方法。您可以使用它来填充一些其他对象(例如 Dictionary<string, object> 或您定义的强类型类),然后您可以将其交给序列化程序以生成 JSON。

试试下面的代码。 (另请注意 @Jon Skeet 提到的 using 语句和参数化 SQL 的使用符合良好的编码实践。)

public static string GetDetails(int Id)
{
    string con = "server=FACULTY01\\SQLSERVER2012ENT; database=SampleDb; uid=sa; pwd=sa9";
    using (SqlConnection scon = new SqlConnection(con))
    {
        string qry = "Select * from Information where ID = @id";
        SqlCommand cmd = new SqlCommand(qry, scon);
        cmd.Parameters.AddWithValue("@id", Id);
        scon.Open();

        var details = new Dictionary<string, object>();

        using (SqlDataReader rdr = cmd.ExecuteReader())
        {
            if (rdr.HasRows && rdr.Read())
            {
                for (int i = 0; i < rdr.FieldCount; i++)
                {
                    details.Add(rdr.GetName(i), rdr.IsDBNull(i) ? null : rdr.GetValue(i));
                }
            }
        }

        JavaScriptSerializer jss = new JavaScriptSerializer();
        string jsonDoc = jss.Serialize(details);
        scon.Close();
        return jsonDoc;
    }
}

请注意,上面的代码期望从阅读器返回一行。如果您期望不止一行,那么您将需要使用另一个循环并将结果数据放入 List&lt;Dictionary&lt;string, object&gt;&gt; 中。这是您需要更改的部分:

        ...

        var details = new List<Dictionary<string, object>>();

        using (SqlDataReader rdr = cmd.ExecuteReader())
        {
            if (rdr.HasRows)
            {
                while (rdr.Read())
                {
                    var dict = new Dictionary<string, object>();

                    for (int i = 0; i < rdr.FieldCount; i++)
                    {
                        dict.Add(rdr.GetName(i), rdr.IsDBNull(i) ? null : rdr.GetValue(i));
                    }

                    details.Add(dict);
                }
            }
        }

        ...

【讨论】:

    【解决方案2】:

    您需要一个循环来存储来自阅读器的数据。使用 DataTable 存储完整的表。单个变量将存储单列数据。

    while (rdr.Read())
    {
        var details = rdr["columnName"];
    }
    

    【讨论】:

      【解决方案3】:

      遇到这篇文章,因为它在谷歌搜索中排名第一。

      已给出答案here(基于this):

      要求有点类似,就是将sqldatareader结果转成json字符串。

      public static class MyExtensions
          {
              public async static Task<string> toJSON(this SqlDataReader reader)
              {            
                  var results = await reader.GetSerialized();
                  return JsonConvert.SerializeObject(results, Formatting.Indented);
              }
              public async static Task<IEnumerable<Dictionary<string, object>>> GetSerialized(this SqlDataReader reader)
              {
                  var results = new List<Dictionary<string, object>>();
                  var cols = new List<string>();
                  for (var i = 0; i < reader.FieldCount; i++)
                      cols.Add(reader.GetName(i));
      
                  while (await reader.ReadAsync())
                      results.Add(SerializeRow(cols, reader));
      
                  return results;
              }
              private static Dictionary<string, object> SerializeRow(IEnumerable<string> cols,
                                                              SqlDataReader reader)
              {
                  var result = new Dictionary<string, object>();
                  foreach (var col in cols)
                      result.Add(col, reader[col]);
                  return result;
              }
          }
      

      用作:

      var result = await reader.GetSerialized(); //to get the result object
      

      string strResult = await reader.toJSON(); //to get the result string
      

      【讨论】:

        猜你喜欢
        • 2015-12-05
        • 1970-01-01
        • 2012-09-13
        • 2015-06-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-02
        • 1970-01-01
        相关资源
        最近更新 更多