我在WEB API应用程序中将数据读取器的结果序列化为JSON。 我没有使用预定义的类来保存读取器中的数据。 将生成的JSON与sql server management studio的结果进行比较。 在两种情况下都执行具有相同参数的相同存储过程。 有8个结果集。 第5个结果集,应该有20行,返回0结果。 第7个结果集包含2行而不是8行。
在这两种情况下,我都使用SO上的代码,我改变了一点: 第一种情况 - 手动创建序列化对象:
public JsonResult<Dictionary<string, List<Dictionary<string, object>>>> Get()
{
Dictionary<string, List<Dictionary<string, object>>> r = null;
using (var conn = new SqlConnection(_connString))
{
using (var command = new SqlCommand("getReportData", conn) { CommandType = CommandType.StoredProcedure })
{
command.Parameters.AddWithValue("@DateFrom", new DateTime(2014, 6, 1, 0, 0, 0));
command.Parameters.AddWithValue("@DateTo", new DateTime(2014, 6, 1, 0, 0, 0));
command.Parameters.AddWithValue("@UserIDList", "1,2,3,4,5,6,7");
conn.Open();
command.ExecuteNonQuery();
reader = command.ExecuteReader();
r = Serialize(reader);
}
}
return Json(r, new JsonSerializerSettings {Formatting = Formatting.Indented});
}
public Dictionary<string, List<Dictionary<string, object>>> Serialize(SqlDataReader reader)
{
string resultSetName = "resultSet_";
int resultSetCount = 1;
var sets = new Dictionary<string, List<Dictionary<string, object>>>();
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 (reader.Read())
results.Add(SerializeRow(cols, reader));
sets.Add(resultSetName + resultSetCount, results);
while (reader.NextResult())
{
resultSetCount++;
var resultsTmp = new List<Dictionary<string, object>>();
var colsTmp = new List<string>();
for (var i = 0; i < reader.FieldCount; i++)
{
colsTmp.Add(reader.GetName(i));
}
while (reader.Read())
{
resultsTmp.Add(SerializeRow(colsTmp, reader));
}
var setTmp = new Dictionary<string, List<Dictionary<string, object>>>();
sets.Add(resultSetName + resultSetCount, resultsTmp);
}
return sets;
}
private 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]);
_loopRowCount++;
return result;
}
第二种情况 - 使用数据适配器,组合字典和序列化结果到json:
public JsonResult<Dictionary<string, DataTable>> Get()
{
string setName = "resultSet_";
int setCount = 1;
var dataTables = new Dictionary<string, DataTable>();
using (var connection = new SqlConnection(_connString))
{
using (var command = new SqlCommand("getReportData", connection) { CommandType = CommandType.StoredProcedure })
{
command.Parameters.AddWithValue("@DateFrom", new DateTime(2014, 6, 1, 0, 0, 0));
command.Parameters.AddWithValue("@DateTo", new DateTime(2014, 6, 1, 0, 0, 0));
command.Parameters.AddWithValue("@UserIDList", "1,2,3,4,5,6,7");
connection.Open();
var adapter = new SqlDataAdapter(command);
var set = new DataSet();
adapter.SelectCommand = command;
adapter.Fill(set);
foreach (DataTable t in set.Tables)
{
dataTables.Add(setName + setCount, t);
setCount++;
}
}
}
return Json(dataTables, new JsonSerializerSettings { Formatting = Formatting.Indented });
}
以下是在SSMS中执行存储过程的代码
USE [DB]
GO
DECLARE @return_value int
EXEC @return_value = [dbo].[getReportData]
@DateFrom = '2013-06-01 00:00:00',
@DateTo = '2013-06-30 00:00:00',
@UserIDList = '1,2,3,4,5,6,7'
SELECT 'Return Value' = @return_value
GO
两种方法都会错过完全相同的数据,而执行存储过程会清楚地返回更多数据。 我重复一遍,相同的存储过程,在所有三种情况下都有相同的参数。
有一件奇怪的事情是生产代码使用这个存储过程,但是将数据从阅读器映射到预定义的类,没有数据丢失。
为什么读者会“忽略”程序明显返回的数据以及如何防止这种情况?
答案 0 :(得分:1)
在发布的代码中,@DateFrom
和@DateTo
的值在SSMS与C#中执行时会有所不同。