2010-04-08 52 views
2

在嘗試了許多在互聯網上列出的解決方案之後,我現在非常困惑。我有一個C#/ SQL Web應用程序,我只是試圖將一個ExecuteReader命令綁定到一個Dropdownlist,以便用戶可以選擇一個值。這是一個XP OS上的VS2008項目。Dropdownlist和Datareader

工作原理是在用戶選擇一個表之後,我使用這個選擇作爲Datamatch.aspx.cs文件中一個方法的輸入參數。然後這個Datamatch.aspx.cs文件從我的ADONET.cs類文件中調用一個方法。最後,這個方法執行一個SQL過程來從該表中返回列的列表。 (這些都是Adventureworks數據庫中的所有表格)。我知道如果我在SSMS中執行這個SP,這個方法會成功返回列的列表。但是,我不知道如何判斷它是否在VS中工作。

這應該很簡單。我怎樣才能做到這一點?這是我的一些代碼。在T-SQL存儲過程:

CREATE PROCEDURE [dbo].[getColumnNames] 
@TableName VarChar(50) AS 
BEGIN 
SET NOCOUNT ON; 
SELECT col.name 'COLUMN_NAME' FROM sysobjects obj 
INNER JOIN syscolumns col ON obj.id = col.id 
WHERE obj.name = @TableName 
END 

它給了我,當我執行從SSMS以下所需的輸出:exec getColumnNames 'AddressType'

而且從Datamatch.aspx.cs代碼文件目前是:

私人無效CreateDropDownLists() SqlDataReader dr2 = ADONET_methods.DisplayTableColumns(targettable);

int NumControls = targettable.Length; 
DropDownList ddl = new DropDownList(); 
DataTable dt = new DataTable(); 

dt.Load(dr2); 

ddl.DataValueField = "id"; 
ddl.DataTextField = "text"; 
ddl.DataSource = dt; 
ddl.DataBind(); 

for (int counter = 0; counter < NumberOfControls; counter++) 
{ 
    ddl.ID = "DropDownListID " + (counter + 1).ToString(); 
    btnSubmit.Style.Add("top", "auto"); 
    btnSubmit.Style.Add("left", "auto"); 
    btnSubmit.Style.Add("position", "absolute"); 

    if (counter < 7) 
    { 
     ddl.Style["top"] = 100 * counter + 80 + "px"; 
     ddl.Style["left"] = 250 + "px"; 
     int bSubmitPosition = NumberOfControls * 100 + 80; 
     btnSubmit.Style.Add("top", System.Convert.ToString(bSubmitPosition) + "px"); 
    } 
    else if (counter >= 7) 
    { 
     ddl.Style["top"] = 100 * counter - 620 + "px"; 
     ddl.Style["left"] = 550 + "px"; 
     int bSubmitPosition = NumberOfControls * 100 - 620; 
     btnSubmit.Style.Add("top", System.Convert.ToString(bSubmitPosition) + "px"); 
    } 
    ddl.SelectedIndexChanged += new EventHandler(SelectedIndexChanged); 
    ddl_ht.Add(counter, ddl.SelectedValue); 

    pnlDisplayData.Controls.Add(ddl); 
    pnlDisplayData.Controls.Add(new LiteralControl("<br><br><br>")); 
    pnlDisplayData.Visible = true; 
    pnlDisplayData.FindControl(ddl.ID); 
    // dr.Close(); 
} 

}

私人無效CreateLabels() { 對(INT計數器= 0;計數器< NumberOfControls;計數器++){ 標籤 LBL =新標籤(); lbl.ID =「Label」+ counter.ToString(); lbl.Text = headers [counter]; lbl.Style [「position」] =「absolute」; (計數器< 7) lbl.Style [「top」] = 100 * counter + 50 +「px」;如果(計數器<7) lbl。 lbl.Style [「left」] = 250 +「px」; (計數器> = 7) lbl.Style [「top」] =(100 * counter) - 650 +「px」; lbl.Style [「left」] = 550 +「px」; }

pnlDisplayData.Controls.Add(lbl); 
    pnlDisplayData.Controls.Add(new LiteralControl("<br><br><br>")); 
} 

}

凡ADONET_methods.DisplayTableColumns(targettable)爲:

public static SqlDataReader DisplayTableColumns(string tt) 
    { 
     SqlDataReader dr = null; 
     string TableName = tt; 
     string connString = "Server=(local);Database=AdventureWorks;Integrated Security = SSPI"; 
     string errorMsg; 
     SqlConnection conn2 = new SqlConnection(connString); 
     SqlCommand cmd = new SqlCommand("getColumnNames"); //conn2.CreateCommand(); 

     try 
     { 
      cmd.CommandType = CommandType.StoredProcedure; 
      cmd.Connection = conn2; 
      SqlParameter parm = new SqlParameter("@TableName", SqlDbType.VarChar); 
      parm.Value = "Person." + TableName.Trim(); 
      parm.Direction = ParameterDirection.Input; 
      cmd.Parameters.Add(parm); 
      conn2.Open(); 
      dr = cmd.ExecuteReader(); 

     } 
     catch (Exception ex) 
     { 
      errorMsg = ex.Message; 
     } 
     return dr; 
    } 

上述CreateLabels方法正確地顯示我的標籤。但是CreateDropDownLists方法只顯示了一個沒有任何內容的下拉列表。換句話說,它是不可選擇的。 那麼如何驗證datareader是否返回所有4列並檢查其值?我能夠從datareader「COLUMN_NAME」中找到,但我不知道要驗證列名稱的搜索屬性。

+0

在某個點上是否有錯誤信息? – 2010-04-08 23:34:42

+0

僅供參考,** SqlDataReaders **是IDisposable,真的**真**不應該離開它們創建的範圍,特別是不填充下拉列表。您應該將所有數據讀入內存集合並返回。 – R0MANARMY 2010-04-09 04:06:33

+0

沒有錯誤。但現在只有一個下拉列表顯示,而且是空的! Romanarmy,你能詳細解釋一下如何做到這一點嗎? 我正在用我最新的嘗試更新我的問題。 – salvationishere 2010-04-09 05:33:03

回答

2

它看起來並不像你實際上在這個代碼中的任何地方綁定下拉菜單。你需要做這樣的事情:

ddl.DataTextField = "COLUMN_NAME"; 
ddl.DataValueField = "COLUMN_NAME"; 
ddl.DataSource = dr.ExecuteReader(); 
ddl.DataBind(); 

或者,你都可以在你的頁面的標記使用SqlDataSource控件做到這一點。

<asp:SqlDataSource 
     id="SqlDataSource1" 
     runat="server" 
     DataSourceMode="DataSet" 
     ConnectionString="myConnString" 
     SelectCommand="myStoredProcedure" 
     > 
    </asp:SqlDataSource> 

    <asp:MyDropDownList id="ddl" runat="server" DataSource="SqlDataSource1" 
     DataTextField="COLUMN_NAME" DataValueField="COLUMN_NAME" /> 
+0

結帳我現在編輯的問題。感謝您的提示! – salvationishere 2010-04-09 05:33:22

2

在ADONET_methods.DisplayTableColumns(targettable)方法返回博士之前,使用斷點

string temp; 
while(dr.Read()) 
{ 
    temp = dr.GetValue(); //use a breakpoint here 
} 

此外,而不是使用的DataReader,並加載它檢查是否得到dr.GetValue一些價值()到dataTable,你可以更好地使用dataAdapter來直接填充數據表

public static DataTable DisplayTableColumns(string tt) 
{ 
    Datatable dt = new DataTable(); 
    SqlDataAdapter da = new SqlDataAdapter(); 

    try 
    { 
     da.Fill(dt); 
    } 
    catch (Exception ex) 
    { 
     errorMsg = ex.Message; 
    } 

    string temp; 
    foreach(DataRow row in dt.Rows) 
    { 
     foreach(DataColumn column in dt.Columns) 
     { 
      temp = (row[column]); // use your breakpoint here 
     } 
    } 

    return dt; 
} 
+0

謝謝你們的幫助!但是我發現真正的問題是我給這個SQL存儲過程輸入了錯誤的值:「Person.AddressType」而不是「AddressType」。我現在解決了這個問題,現在這個工作正常! – salvationishere 2010-04-09 09:35:08

+0

@salvationishere:這個解決方案對於返回一個原始的'DataReader'仍然是一個改進。如果有的話,你應該嘗試使用Linq to SQL。 – R0MANARMY 2010-04-09 22:20:21