2014-11-08 2 views
0

데이터 판독기의 결과를 WEB API 응용 프로그램의 JSON에 직렬화합니다. 미리 정의 된 클래스를 사용하여 판독기의 데이터를 보유하지 않습니다. 결과 JSON이 SQL Server Management Studio의 결과와 비교됩니다. 두 경우 모두 동일한 매개 변수를 사용하는 동일한 저장 프로 시저가 실행되고 있습니다. 8 개의 결과 집합이 있습니다. 다섯 번째 결과 집합, 20 개의 행이 있어야 0 개의 결과가 반환됩니다.일부 결과 집합에서 결과를 건너 뛰는 SqlDataReader

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; 
    } 
: - 수동으로 직렬화 객체를 생성 1 일 경우 : 7 결과 집합은, 내가 조금 변경 SO에 여기 코드를 사용하고 2 행 대신 두 경우 모두 8

을 포함

는 2 케이스 -, 네트워크 어댑터를 사용하여 사전 구성 및 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

게시 된 코드에서 SSMS와 C#에서 실행될 때 @DateFrom@DateTo의 값이 다릅니다.

관련 문제