从SqlDataReader转换为JSON

public string toJSON(SqlDataReader o) { StringBuilder s = new StringBuilder(); s.Append("["); if (o.HasRows) while (o.Read()) s.Append("{" + '"' + "Id" + '"' + ":" + o["Id"] + ", " + '"' + "CN" + '"' + ":" + o["CatName"] + ", " + '"' + "Ord" + '"' + ":" + o["Ord"] + "," + '"' + "Icon" + '"' + ":" + o["Icon"] + "}, "); s.Remove(s.Length - 2, 2); s.Append("]"); o.Close(); return s.ToString(); } 

我在这里使用我自己的函数来进行序列化。 我需要知道这是一个好方法还是我应该使用另一个。 顺便说一下,我曾尝试使用JavaScriptSerializer但这不适用于SqlDataReader。 感谢名单

如果你想要转换为任意JSON的东西,你可以通过将它序列化为Dictionary(Of string,object)进行转换:

 public IEnumerable> Serialize(SqlDataReader reader) { var results = new List>(); var cols = new List(); for (var i = 0; i < reader.FieldCount; i++) cols.Add(reader.GetName(i)); while (reader.Read()) results.Add(SerializeRow(cols, reader)); return results; } private Dictionary SerializeRow(IEnumerable cols, SqlDataReader reader) { var result = new Dictionary(); foreach (var col in cols) result.Add(col, reader[col]); return result; } 

然后使用NewtonSoft.Json JsonConvert对象获取您的JSON:

 var r = Serialize(reader); string json = JsonConvert.SerializeObject(r, Formatting.Indented); 

更新:如果您只是想使用内置方法,而您恰好使用MVC,则可以在新序列化中使用内置的Json辅助方法:

 JsonResult Index(int id) { var r = Serialize(reader); return Json(r, JsonRequestBehavior.AllowGet); } 

另一个选择是使用James Newton-King优秀的JSON.NET库 – http://www.newtonsoft.com/json

这是一个快速示例,介绍如何使用它来构建集合,然后将其作为JSON序列化字符串输出:

 using Newtonsoft.Json; class Program { static void Main(string[] args) { ArrayList objs = new ArrayList(); //get the data reader, etc. while(o.Read()) { objs.Add(new { Id = o["Id"], CN = o["CatName"], Ord = o["Ord"], Icon = o["Icon"] }); } //clean up datareader Console.WriteLine(JsonConvert.SerializeObject(objs)); Console.ReadLine(); } } 

通过将SqlDataReader的每一行读入一个匿名对象,然后使用JSON.NET将其序列化为字符串,您可以对循环执行相同的操作。

希望这可以帮助!

我遇到的情况是,数据读取器返回的行数可能会在内存消耗方面出现问题。 以下代码在流上使用JsonWriter(来自JSON.NET)。 人们当然可以辩论巨大的JSON文档的效用,但有时我们的用例是由其他人决定的:-)

几点说明:

  • 我的SqlDataReader可能包含多个结果集(’tables’)
  • 我可能会将输出发送到FileStream或HttpResponse流
  • 我’抽象’我的对象名称以匹配每个结果集返回的第一列
  • 由于可能存在大型结果集,因此我使用SqlDataReader的异步方法。
  • 我让JSON.NET处理数据读取器结果中包含的实际数据的所有序列化问题。

代码:

 var stream = ... // In my case, a FileStream or HttpResponse stream using (var writer = new JsonTextWriter(new StreamWriter(stream))) { writer.WriteStartObject(); do { int row = 0; string firstColumn = null; while (await reader.ReadAsync()) { if (row++ == 0) { firstColumn = reader.GetName(0); writer.WritePropertyName(string.Format("{0}Collection", firstColumn)); writer.WriteStartArray(); } writer.WriteStartObject(); for (int i = 0; i < reader.FieldCount; i++) { if (!reader.IsDBNull(i)) { writer.WritePropertyName(reader.GetName(i)); writer.WriteValue(reader.GetValue(i)); } } writer.WriteEndObject(); } writer.WriteEndArray(); } while (await reader.NextResultAsync()); writer.WriteEndObject(); } 

异构输出的一个例子是:

 { "ContactCollection": { "ContactItem": [{ "ContactID": "1", "Contact": "Testing", }, { "ContactID": "2", "Contact": "Smith, John", }, { "ContactID": "4", "Contact": "Smith, Jane", } ], "MessageItem": [{ "MessageID": "56563", "Message": "Contract Review Changed", }, { "MessageID": "56564", "Message": " Changed", }, { "MessageID": "56565", "Message": "Contract Review - Estimated Completion Added.", } ] } } 

参考:

试试这个:

 o = cmd.ExecuteReader(); var dataQuery = from d in o.Cast() select new { Id = (String)d["Id"], CN = (String)d["CatName"], Ord = (String)d["Ord"], Icon = (String)d["Icon"] }; var data = dataQuery.ToArray(); JavaScriptSerializer serializer = new JavaScriptSerializer(); String jsonData = serializer.Serialize(data); 

这应该做的工作

 private String sqlDatoToJson(SqlDataReader dataReader) { var dataTable = new DataTable(); dataTable.Load(dataReader); string JSONString = string.Empty; JSONString = JsonConvert.SerializeObject(dataTable); return JSONString; } 

我根据Jonathan的回答使用这段代码:

 private IEnumerable> ConvertToDictionary(IDataReader reader) { var columns = new List(); var rows = new List>(); for (var i = 0; i < reader.FieldCount; i++) { columns.Add(reader.GetName(i)); } while (reader.Read()) { rows.Add(columns.ToDictionary(column => column, column => reader[column])); } return rows; } 

然后:

 var rows = this.ConvertToDictionary(reader); return JsonConvert.SerializeObject(rows, Formatting.Indented); 

这不可能那么难。 当我想将搜索结果作为JSON返回到网页时,这就是我所做的。

首先,有这样一个类

 public class SearchResult { public string model_no { get; set; } public string result_text { get; set; } public string url { get; set; } public string image_url { get; set; } } 

然后有下面的代码。

  string sql_text = "select * from product_master where model_no like @search_string and active=1"; SqlConnection connection = new SqlConnection(sql_constr); SqlCommand cmd = new SqlCommand(sql_text, connection); cmd.Parameters.AddWithValue("@search_string", "%" + search_string + "%"); connection.Open(); SqlDataReader rdr = cmd.ExecuteReader(); List searchresults = new List(); while (rdr.Read()) { SearchResult sr = new SearchResult(); sr.model_no = rdr["model_no"].ToString(); sr.result_text = rdr["product_name"].ToString(); sr.url = rdr["url_key"].ToString(); searchresults.Add(sr); } connection.Close(); //build json result return Json(searchresults, JsonRequestBehavior.AllowGet); 

这对我很有用..

这是为了增强Chandu使用查询语法的Linq答案(来自… select …)。 如果您更喜欢方法语法,这是您的答案。

 drdr = cmd.ExecuteReader(); Record[] recs = drdr.Cast().Select( data=>new Record{ GraphID=(drdr.IsDBNull(0) ? "" : (string)data["LabelX"]) , XAxis=(drdr.IsDBNull(1) ? "1999-09-09 00:00:00" : Convert.ToDateTime(data["XDate"]).ToString("yyyy-MM-dd HH:mm:ss")) , YVal=(drdr.IsDBNull(2) ? 0 : int.Parse(data["YFreq"].ToString())) }).ToArray(); MemoryStream mem = new MemoryStream(); DataContractJsonSerializer szr = new DataContractJsonSerializer(typeof(Record[])); szr.WriteObject(mem, recs); String jsonData = Encoding.UTF8.GetString(mem.ToArray(), 0, (int)mem.Length); 

希望它对某人有帮助。

继Jonathan的答案之后,我在ASP.NET Core中有类似的要求将SQLDataReader的结果转换为JSON字符串或结果对象,因此我为它创建了一个扩展方法:

  public static class MyExtensions { public async static Task toJSON(this SqlDataReader reader) { var results = await reader.GetSerialized(); return JsonConvert.SerializeObject(results, Formatting.Indented); } public async static Task>> GetSerialized(this SqlDataReader reader) { var results = new List>(); var cols = new List(); 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 SerializeRow(IEnumerable cols, SqlDataReader reader) { var result = new Dictionary(); 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 

我创建了一个异步方法,因为在从数据库完成读取之前我还有其他一些事情要做。

自SQL Server 2016以来,Microsoft使用sql查询嵌入了此function。 您可以在查询结束时使用FOR JSON关键字来实现它。

 select * from table_example where somecolumn = somecondition FOR JSON AUTO 

有关更多详细信息和示例,您可以使用自动模式(SQL Server)自动执行此官方文档格式JSON输出

以下是Microsoft的C#代码示例,用于从SQL查询中获取JSON字符串。

 var queryWithForJson = "SELECT ... FOR JSON"; var conn = new SqlConnection(""); var cmd = new SqlCommand(queryWithForJson, conn); conn.Open(); var jsonResult = new StringBuilder(); var reader = cmd.ExecuteReader(); if (!reader.HasRows) { jsonResult.Append("[]"); } else { while (reader.Read()) { jsonResult.Append(reader.GetValue(0).ToString()); } } 

警告:此解决方案仅对SQL SERVER 2016及更高版本有效。

我做了以下方法,它将任何DataReader转换为JSON,但仅用于单深度序列化:

你应该传递阅读器,并将列名称作为字符串数组,例如:

 String [] columns = {"CustomerID", "CustomerName", "CustomerDOB"}; 

然后调用该方法

 public static String json_encode(IDataReader reader, String[] columns) { int length = columns.Length; String res = "{"; while (reader.Read()) { res += "{"; for (int i = 0; i < length; i++) { res += "\"" + columns[i] + "\":\"" + reader[columns[i]].ToString() + "\""; if (i < length - 1) res += ","; } res += "}"; } res += "}"; return res; } 

添加引用: System.Web.Extensions然后进行项目

 using System.Web.Script.Serialization; 

在c#代码中,您可以使用write:

  var json = new JavaScriptSerializer().Serialize(obj); 

使用Cinchoo ETL (一个开源库),您可以使用几行代码轻松地将SqlDataReader导出为JSON

 string connectionstring = @"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=Northwind;Integrated Security=True"; StringBuilder sb = new StringBuilder(); using (var conn = new SqlConnection(connectionstring)) { conn.Open(); var comm = new SqlCommand("SELECT top 2 * FROM Customers", conn); using (var parser = new ChoJSONWriter(sb)) parser.Write(comm.ExecuteReader()); } Console.WriteLine(sb.ToString()); 

输出:

 [ { "CustomerID": "ALFKI", "CompanyName": "Alfreds Futterkiste", "ContactName": "Maria Anders", "ContactTitle": "Sales Representative", "Address": "Obere Str. 57", "City": "Berlin", "Region": {}, "PostalCode": "12209", "Country": "Germany", "Phone": "030-0074321", "Fax": "030-0076545" }, { "CustomerID": "ANATR", "CompanyName": "Ana Trujillo Emparedados y helados", "ContactName": "Ana Trujillo", "ContactTitle": "Owner", "Address": "Avda. de la Constitución 2222", "City": "México DF", "Region": {}, "PostalCode": "05021", "Country": "Mexico", "Phone": "(5) 555-4729", "Fax": "(5) 555-3745" } ]