2013-07-26 64 views
0

我有一個類中的方法,它包含SqlDataReader(它連接到數據庫表並檢索多行)。 後來我想將SqlDataReader所具有的每條記錄都分配給asp標籤。但我不知道什麼應該是方法的返回類型,所以我可以從中提取值,以及如何在代碼後面執行該操作。 這裏是代碼;SqlDataReader方法的返回類型

public (???) displayCustoemrhShipOrder() 
    { 
     string htmlStr = string.Empty;     
     string sConnectionString = ConfigurationManager.ConnectionStrings["LGDB"].ToString(); 
     SqlConnection SqlCOn = new SqlConnection(sConnectionString); 
     SqlCommand SqlCmd = new SqlCommand(); 
     SqlCmd.Connection = SqlCOn; 
     SqlCmd.CommandText = "displayCustomerShipOrder"; 
     SqlCmd.CommandType = CommandType.StoredProcedure; 
     SqlCOn.Open(); 
     SqlCmd.Parameters.AddWithValue("ShipOrderID",shipOrderID); 
     SqlDataReader reader = SqlCmd.ExecuteReader(); 
     while (reader.Read()) 
     { 
      htmlStr = reader.GetInt32(0).ToString(); 
     } 
     reader.Close(); 
     SqlCOn.Close();    
     return(???) 
    } 
+0

的方法,我想可以指定由數據讀取器獲取的數據以asp標籤! – Iatrochemist

回答

2

通常,您不應該將SqlDataReader返回到數據庫訪問代碼之外的圖層。這個一般原則背後的原因是SqlDataReader是一個非常「昂貴」的對象,保持與數據庫的開放連接!所以,如果你保留SqlDataReader左右,那不是很糟糕,但是如果你在任何特定時間保持10個左右的位置?他們中的100個呢? 1000?這是一個災難的祕訣。

那麼如何關閉從SqlDataReader到數據庫的連接呢? .NET在IDisposable界面中有一個非常方便的方法,稱爲Dispose(),它將負責爲您進行清理。所以你的代碼可能看起來像

function getData() 
{ 
    // instantiate SqlDataReader from SqlCommand, call it "rdr" 
    rdr.Dispose(); 
} 

但實際上這個代碼有問題。如果你的代碼在得到Dispose()之前拋出一個異常呢?它應該看起來像

function getData() 
{ 
    try{ 
     // instantiate SqlDataReader from SqlCommand, call it "rdr" 
    } 
    catch(Exception){} 
    Finally{ 
     rdr.Dispose(); 
    } 
} 

這非常詳細!如果你不想輸入所有這些?別擔心,.NET也會爲你處理這個問題。這樣做:

public (???) displayCustoemrhShipOrder() 
{ 
    string htmlStr = string.Empty;     
    string sConnectionString = ConfigurationManager.ConnectionStrings["LGDB"].ToString(); 
    using(SqlConnection SqlCOn = new SqlConnection(sConnectionString)) 
    { 
    using(SqlCommand SqlCmd = new SqlCommand()) 
    { 
    SqlCmd.Connection = SqlCOn; 
    SqlCmd.CommandText = "displayCustomerShipOrder"; 
    SqlCmd.CommandType = CommandType.StoredProcedure; 
    SqlCOn.Open(); 
    SqlCmd.Parameters.AddWithValue("ShipOrderID",shipOrderID); 
    using(SqlDataReader reader = SqlCmd.ExecuteReader()) 
    while (reader.Read()) 
    { 
     htmlStr = reader.GetInt32(0).ToString(); 
    } 
    // reader.Close(); // this line becomes optional, Dispose() will call Close() 
    } 
    // SqlCOn.Close(); // this line becomes optional, Dispose() will call Close() 
    } 
    } 

    return(???) 
} 

這是說,如果你知道你需要Dispose()Close() SqlDataReader中的所有迂迴的方式,而且一旦你做,你不能得到的數據出來,那麼你顯然不應該將它返回給需要處理數據的代碼(但不一定是它所處理的數據庫連接)。我建議使用DataTable類,你可以在這裏讀到它:

.NET DataTable class

而且要轉換爲DataTable被稱爲DataTable.Load(SqlDatareader...在表示層

+0

非常感謝您的全面回答,對於像我這樣的初學者非常有用。但後來我想從數據讀取器分配數據到asp標籤,是否真的使用數據表類? – Iatrochemist

+1

數據庫訪問類可以返回一個DataTable類實例,然後可以通過遍歷DataTable.Rows將該DataTable實例轉換爲任何你想要的,這與DataReader.Read()完全一樣,除了它將不會使用打開的數據庫連接。這有點低效,因爲你對數據進行了2次迭代,一次是'DataReader'中的'DataTable',另一次'DataTable'中的一次是使你的'List '。您可以通過直接從'DataReader.Read'中的數據實例化'YourObject ...'來跳過DataTable類。 – welegan

+1

但是我不推薦直到有更多經驗,因爲保持'DataReader'打開更長時間,或者即使保持開放時間更長的風險也可能會帶來巨大的負面影響,但收益並不大 – welegan

1

可以每個單獨的值增加List<string>回它和方法的使用外。