2014-11-08 3 views
0

Я сериализую результаты чтения данных в JSON внутри приложения WEB API. Я не использую предопределенные классы для хранения данных от читателя. Результаты JSON сравниваются с результатами работы студии управления сервером sql. В обоих случаях выполняется одна и та же хранимая процедура с теми же параметрами. Имеется 8 наборов результатов. Пятый результирующий набор, который должен содержать 20 строк, возвращает 0 результатов. седьмого результирующий набор содержит 2 строки вместо 8.SqlDataReader пропускает результаты в некоторых наборах результатов

В обеих случаях я использую код найден здесь на 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

Вы можете показать, как хранится процедура в SSMS? –

+0

Вопрос обновляется с образцом кода, который выполняет хранимую процедуру. –

+0

- это правильно? значения '@ DateFrom' и' @ DateTo' отличаются (выполняются в SSMS против C#). –

ответ

1

От вашего опубликованного кода значения @DateFrom и @DateTo отличаются при исполнении в SSMS против C#.

Смежные вопросы