2016-05-12 69 views
0

我有一個函數(PopulateStudents)用數據庫的結果填充下拉列表。該函數在兩種不同的情況下被調用:提供帶有id的查詢字符串和onselectedindexchanged事件。基本上,如果通過URL提供了一個ID,那麼獲取包含學期ID和courseID的學生ID的數據庫記錄。然後,根據studentID填充所有的DDL。ASP C#在讀取器關閉時無效嘗試調用FieldCount

如果URL中沒有ID,則用戶從DDL中選擇一個學期。然後根據在學期DDL中選擇的學期ID填寫DDL課程。然後,根據所選課程填充學生DDL。

問題是,當查詢字符串中沒有提供ID時,PopulateStudent函數可以正常工作,並且用戶必須選擇學期然後選擇課程。在查詢字符串中提供ID時,PopulateStudents函數不起作用。該函數拋出一個錯誤,說Invalid attempt to call FieldCount when reader is closed.我的代碼有什麼問題?

這裏是aspx.cs文件:

protected void Page_Load(object sender, EventArgs e) 
     { 

      if (!IsPostBack) 
      { 
       if (Request.QueryString["id"] != null) 
       { 
        GetStudentScores(Convert.ToInt32(Request.QueryString["id"])); 

        string connString; 
        connString = RetrieveConnectionString(); 

        SqlConnection conn = new SqlConnection(connString); 

        try 
        { 
         using (conn) 
         { 
          conn.Open(); 
          SqlCommand cmd = new SqlCommand("dbo.GetEnrolleeDetails", conn); 
          cmd.Parameters.Add("@enrollmentID", System.Data.SqlDbType.Int); 
          cmd.Parameters["@enrollmentID"].Value = Convert.ToInt32(Request.QueryString["id"]); 

          cmd.CommandType = System.Data.CommandType.StoredProcedure; 

          SqlDataReader reader = cmd.ExecuteReader(); 
          reader.Read(); 

          int semesterID = Convert.ToInt32(reader["semesterId"]); 
          int courseID = Convert.ToInt32(reader["courseId"]); 

          PopulateCourses(semesterID); 
          PopulateStudents(courseID); 

          DDSemester.SelectedValue = Convert.ToString(semesterID); 
          DDCourse.SelectedValue = Convert.ToString(courseID); 
          DDStudent.SelectedValue = Request.QueryString["ID"]; 
         } 
        } 
        catch (Exception err) 
        { 
         lblStatus.Text = err.Message; 
        } 
        finally 
        { 
         conn.Close(); 
         conn.Dispose(); 
        } 
       } 
      } 
     } 

     protected void DDCourse_SelectedIndexChanged(object sender, EventArgs e) 
     { 
      if (IsPostBack) 
      { 
       PopulateStudents(Convert.ToInt32(DDCourse.SelectedValue)); 
      } 
     } 



     protected void DDStudent_SelectedIndexChanged(object sender, EventArgs e) 
     { 
      if (IsPostBack) 
      { 
       GetStudentScores(Convert.ToInt32(DDStudent.SelectedValue)); 
      } 
     } 

     protected void DDSemester_SelectedIndexChanged(object sender, EventArgs e) 
     { 
      if (IsPostBack) 
      { 
       PopulateCourses(Convert.ToInt32(DDSemester.SelectedValue)); 
      } 
     } 

     private void PopulateCourses(int semesterID) 
     { 
      string connString; 
      connString = RetrieveConnectionString(); 

      SqlConnection conn = new SqlConnection(connString); 

      try 
      { 
       using (conn) 
       { 
        conn.Open(); 
        SqlCommand cmd = new SqlCommand("dbo.GetSemesterCourses", conn); 
        cmd.Parameters.Add("@semesterID", System.Data.SqlDbType.Int); 
        cmd.Parameters["@semesterID"].Value = semesterID; 

        cmd.CommandType = System.Data.CommandType.StoredProcedure; 

        DDCourse.DataSource = cmd.ExecuteReader(); 
        DDCourse.DataTextField = "courseName"; 
        DDCourse.DataValueField = "courseId"; 
        DDCourse.DataBind(); 
       } 
      } 
      catch (Exception err) 
      { 
       lblStatus.Text = err.Message; 
      } 
      finally 
      { 
       conn.Close(); 
       conn.Dispose(); 
      } 
     } 

     private void PopulateStudents(int courseID) 
     { 
      string connString; 
      connString = RetrieveConnectionString(); 

      SqlConnection conn = new SqlConnection(connString); 

      try 
      { 
       using (conn) 
       { 
        conn.Open(); 
        SqlCommand cmd = new SqlCommand("dbo.CourseEnrollment", conn); 
        cmd.Parameters.Add("@courseId", System.Data.SqlDbType.Int); 
        cmd.Parameters["@courseId"].Value = courseID; 

        cmd.CommandType = System.Data.CommandType.StoredProcedure; 

        DDStudent.DataSource = cmd.ExecuteReader(); 
        DDStudent.DataTextField = "fullName"; 
        DDStudent.DataValueField = "enrollmentId"; 
        this.DataBind(); 
       } 
      } 
      catch (Exception err) 
      { 
       lblStatus.Text = err.Message; 
      } 
      finally 
      { 
       conn.Close(); 
       conn.Dispose(); 
      } 
     } 

這裏是ASP:

<asp:Label ID="Label1" runat="server" Text="Semester:"></asp:Label> 
    <asp:DropDownList ID="DDSemester" runat="server" AutoPostBack="True" AppendDataBoundItems="true" DataSourceID="SqlDataSource1" DataTextField="semesterName" DataValueField="semesterId" OnSelectedIndexChanged="DDSemester_SelectedIndexChanged">  
       <asp:ListItem Text="Select a Semester"></asp:ListItem> 
    </asp:DropDownList><br /> 

    <asp:Label ID="Label15" runat="server" Text="Course:"></asp:Label> 
    <asp:DropDownList ID="DDCourse" runat="server" AutoPostBack="True" AppendDataBoundItems="true" OnSelectedIndexChanged="DDCourse_SelectedIndexChanged"> 
     <asp:ListItem Text="Select a Course"></asp:ListItem> 
    </asp:DropDownList><br /> 

    <asp:Label ID="Label16" runat="server" Text="Student"></asp:Label> 
    <asp:DropDownList ID="DDStudent" runat="server" AutoPostBack="true" AppendDataBoundItems="true" OnSelectedIndexChanged="DDStudent_SelectedIndexChanged"> 
     <asp:ListItem Text="Select a Student"></asp:ListItem> 
    </asp:DropDownList><br /> 

感謝您的時間。

+1

您應該只在using語句的範圍內創建連接,例如'使用(var conn = new SqlConnection(connString){'。這樣,你不需要任何這些手動關閉/處理調用。可能不是解決方案,但它應該通過簡化代碼有所幫助。到任何Reader對象和SqlCommands。基本上,在任何地方你可以在這裏使用using語句,這樣做:) – ManoDestra

回答

0

PopulateCourses和PopulateStudents函數實際上有一個區別,我沒注意到。在課程中,我使用DDCourse.DataBind(),並在學生中使用this.DataBind()。

在populatestudents函數中,將this.DataBind()更改爲DDStudent.DataBind()修復了我的問題。

相關問題