通过SqlDataReader从数据库检索数据并将其转换为JSON

3
我想将检索到的数据转换为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;
}

2
请展示完整的堆栈跟踪。此外:1)您应该使用“using”语句;2)您应该使用参数化SQL。 - Jon Skeet
@JonSkeet 亲爱的,我正在使用这个,因为它看起来很好,不需要再写代码了。 - Mangrio
或者有其他方法将reader存储到var中吗?我只想将检索到的数据存储到var中以进行JSON序列化。 - Mangrio
仅仅因为没有更多的代码了,并不意味着就没有了堆栈跟踪。现在还不清楚你的代码是否正在执行——也许这实际上是一个路由问题?(现在还不清楚为什么你有一个details变量,而不是直接调用jss.Serialize(rdr);——好像使用var声明的变量并没有改变什么。) - Jon Skeet
可能是从SqlDataReader转换为JSON的重复问题。 - Abdul Rehman Sayed
3个回答

4
您不能直接序列化SqlDataReader并期望输出包含来自SQL查询的数据。这不是SqlDataReader的工作方式。 SqlDataReader是从SQL结果中检索数据的一种方法。 您可以使用它来填充其他对象(例如您定义的Dictionary<string,object>或强类型类),然后将该对象传递给序列化程序以生成JSON。
请尝试使用下面的代码,同时注意使用using语句和参数化SQL以保持良好的编程实践(如@Jon Skeet所提到的)。
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<Dictionary<string, object>>中。以下是您需要更改的部分:
        ...

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

        ...

1
你需要使用循环来存储读取器中的数据。使用 DataTable 来存储完整的表格,一个变量只能存储单列数据。
while (rdr.Read())
{
    var details = rdr["columnName"];
}

1
在谷歌搜索中遇到了这篇文章。已经在this的基础上给出了一个答案here

要求有些类似,即将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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接