2014-11-19 3 views
1

Первый пост, поскольку я немного застрял здесь.SqlDataReader возвращает x строк, но SQL-запрос возвращает y строк

Я использую этот код, чтобы вернуть некоторые строки из базы данных SQL Server:

public static SqlDataReader SQLSelect(string sqlcommand, string[,] parameters, int length) 
{ 
    try 
    { 
     conn = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString); 
     conn.Open(); 

     SqlDataReader reader; 
     SqlCommand cmd = new SqlCommand(sqlcommand, conn); 

     var allLength = parameters.Length; 

     for (int i = 0; i < parameters.Length - length; i++) 
     { 
      string paramid = parameters[i, 0]; 

      if (paramid == "@date" || paramid == "@Date" || paramid == "@DATE") 
      { 
       string paramvalue = parameters[i, 1]; 
       DateTime date = Convert.ToDateTime(paramvalue); 
       paramvalue = date.ToString("yyyy-MM-dd HH':'mm':'ss"); 

       cmd.Parameters.Add(new SqlParameter(paramid, paramvalue)); 
      } 
      else 
      { 
       string paramvalue = parameters[i, 1]; 
       cmd.Parameters.Add(new SqlParameter(paramid, paramvalue)); 
      } 
     } 

     cmd.CommandType = CommandType.StoredProcedure; 

     reader = cmd.ExecuteReader(); 

     return reader; 
    } 
    catch 
    { 
     return null; 
    } 
} 

Эта функция вызывается как так

string[,] parameters = new string[1, 2] { { "@studentid", studentid } }; 
SqlDataReader reader = Common.SQLSelect(Common.tblstudentprogressselectforprinting, parameters, 1); 

теперь все работает нормально, за исключением того, что читатель содержит только 13 строк данных, где в качестве фактического запроса

exec sp_tblstudentprogress_selectforprinting @studentid=N'87' 

в качестве примера возвращает 91 строку.

Я не понимаю, почему это так. Единственное, что я заметил, - это использовать профилировщик SQL Server, запускать запрос с SQL Server, есть RPC: Started and Completed, поскольку для работы с моим веб-приложением существует только RPC: Started.

Любые мысли по этому поводу?

EDIT:

вот как я перечисляю читателя

 protected void btnPrint_Click(object sender, EventArgs e) 
     { 
      string[,] parameters = new string[1, 2] { { "@studentid", studentid } }; 
      SqlDataReader reader = Common.SQLSelect(Common.tblstudentprogressselectforprinting, parameters, 1); 

      string firstname = txtFirstName.Text; 
      string lastname = txtLastName.Text; 
      int i=0; 
      string[] heading1 = new string[reader.FieldCount]; 
      string[] heading2 = new string[reader.FieldCount]; 
      string[] log = new string[reader.FieldCount]; 

      try 
      { 
       while (reader.Read()) 
       { 
        heading1[i] = "Progress Log for: Block: " + reader["block"].ToString() + " Lesson: " + reader["lesson"].ToString(); 
        heading2[i] = ""; 
        log[i] = 
         /*"PROGRESS LOG for " + reader["firstname"].ToString() + " " + reader["lastname"].ToString() + " Printed on " + DateTime.Today.ToShortDateString() + Environment.NewLine +*/ 
         Environment.NewLine + 
         "Teacher: " + reader["teacher"].ToString() + Environment.NewLine + 
         "Date: " + reader["date"].ToString() + Environment.NewLine + 
         "Year: " + reader["year"].ToString() + Environment.NewLine + 
         "Block: " + reader["block"].ToString() + Environment.NewLine + 
         "Lesson: " + reader["lesson"].ToString() + Environment.NewLine + 
         "Warm Up: " + reader["warmup"].ToString() + Environment.NewLine + 
         "Range: " + reader["range"].ToString() + Environment.NewLine + 
         "Technique Sheet: " + reader["techniquesheet"].ToString() + Environment.NewLine + 
         "Technique Other: " + reader["techniqueother"].ToString() + Environment.NewLine + 
         Environment.NewLine + 
         "Notes: " + reader["notes"].ToString() + Environment.NewLine + 
         Environment.NewLine + 
         "Mark: " + reader["mark"].ToString()+ Environment.NewLine ; 

        i++; 
       } 
      } 
      catch 
      { 

      } 
      finally 
      { 
       if (Common.conn != null) 
       { 
        Common.conn.Close(); 
       } 
      } 


      Common.PDFCreateProgressLog("Progress log for: " + firstname + " " + lastname, "Progress log for: " + firstname + " " + lastname, "PDF_" + firstname + " " + lastname + "-" + DateTime.Today.ToString("yyyy-MM-dd") + ".pdf", "Progress log for: " + firstname + " " + lastname, log, heading1, heading2); 

     } 
+1

Вы, к сожалению, не показываете нам, что вы ** делаете ** с возвращаемым 'SqlDataReader' - как вы перечислите все строки, которые он возвращает? –

+0

Если вы планируете возвращать читателя и не переходить в уже открытое соединение, то вы действительно *** должны делать 'reader = cmd.ExecuteReader (CommandBehavior.CloseConnection);' поэтому, когда читатель получает распоряжение (вы удалив возвращаемого читателя, правильно?), он также закроет соединение. –

+0

Такие различия часто связаны с различными настройками ANSI. Например, ANSI_NULLS отключен по умолчанию при использовании ADO.NET и ON по умолчанию при использовании SQL Server Management Studio. Я предлагаю вам попробовать играть с настройками в Management Studio, пока не получите последовательное поведение. Затем, если это возможно, обновите свой SP, чтобы он не зависел от настроек ANSI. – Joe

ответ

3

Вы путаете смысл FieldCount собственности. Он идентифицирует число Столбцы, а не число Строки. Вы не можете определить общее количество строк из источника потоковой передачи, такого как Reader, без перечисления всех строк сначала (хотя бы один раз, в любом случае).

Так что вам нужно будет продлить свои массивы каждый раз (списки могут быть проще для этого) вы читаете строку из Reader и проверяете Reader, если строк больше нет.

+0

Ах, мой плохой, я понял это сейчас. спасибо за помощь! – Systematic