2012-04-20 71 views
7

我有這樣的代碼:返回一個SqlDataReader

public static SqlDataReader GetGeneralInformation (int RecID) 
{ 
    using (var conn = new SqlConnection(GetConnectionString())) 
    using (var cmd = conn.CreateCommand()) 
    { 
     conn.Open(); 
     cmd.CommandText = 
     @"SELECT cs.Status, cs.Completed 
      FROM NC_Steps s 
      INNER JOIN NC_ClientSteps cs 
       ON cs.RecID = s.RecID 
      WHERE cs.ClientID = 162 
      AND s.RecID = @value"; 
     cmd.Parameters.AddWithValue("@value", RecID); 
     using (var reader = cmd.ExecuteReader()) 
     { 
      if (reader.Read()) 
      { 
       return reader; 
      } 
      return null; 
     } 
    } 
} 

我如何引用呢?

我試過這個,但它不起作用。

SqlDataReader reader = GeneralFunctions.GetGeneralInformation(); 

而且我將如何從閱讀器讀取?

Reader.GetString(reader.GetOrdinal("Status")) 

編輯

現在我收到以下錯誤:

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

下面是更新後的代碼:

public static IEnumerable<IDataRecord> GetGeneralInformation (int ClientID) 
{ 
    using (var conn = new SqlConnection(GetConnectionString())) 
    using (var cmd = conn.CreateCommand()) 
    { 
     conn.Open(); 
     cmd.CommandText = 
     @"SELECT i.GoLiveDate, i.FirstBonusRun, i.TechFName, i.TechLName, i.TechEmail, i.TechPhone, i.WebISPFName, i.WebISPLName, 
      i.WebISPEmail, i.WebISPPhone, i.FullFillFName, i.FullFillLName, i.FullFillEmail, i.FullFillPhone, d.FName, 
      d.LName, d.HomePhone, d.Email 
      FROM NC_Information i 
      INNER JOIN Distributor d 
      ON d.DistID = i.ClientID 
      WHERE clientID = @value"; 
     cmd.Parameters.AddWithValue("@value", ClientID); 
     using (var reader = cmd.ExecuteReader()) 
     { 
      while (reader.Read()) 
      { 
       yield return reader; 
      } 
      yield return null; 
     } 
    } 
} 

protected void Page_Load(object sender, EventArgs e) 
{ 
    IEnumerable<IDataRecord> reader = GeneralFunctions.GetGeneralInformation((int)Session[ "DistID" ]); 

    //string result = GeneralFunctions.GetGeneralInformation(Globals.GeneralInformation).First()[ "Status" ].ToString(); 
} 
+1

爲什麼你不能像讀取其他SqlDataReader一樣閱讀它?它失敗了嗎?如果是這樣,那是因爲你的「使用」語句。在使用閱讀器之前,您正在關閉連接。 – 2012-04-20 19:42:31

+0

@JohnSaunders我試圖讓讀者自己迴歸。我不確定完成我想要做的事情的最佳方式。基本上它是一個填充了數據庫數據的asp.net表單。我能想到的唯一方法就是讓讀者自己回來,這樣我就可以將信息填入asp.net文本框。 – 2012-04-20 19:45:02

+1

您可以返回從閱讀器填充的對象。而你仍然沒有說過什麼是行不通的。 – 2012-04-20 19:46:09

回答

15

的問題是,離開功能(通過回報聲明)將您踢出using塊,因此您正在使用的SqlDataReader和SqlConnections被丟棄。爲了解決這個問題,嘗試改變函數簽名是這樣的:

public static IEnumerable<IDataRecord> GetGeneralInformation (int RecID) 

,然後更新這樣的函數中:

using (var reader = cmd.ExecuteReader()) 
{ 
    while (reader.Read()) 
    { 
     yield return reader; 
    } 
} 

對於最後的「我如何從它讀? 「部分,它可能是這樣的:

string result = reader.First()["Status"].ToString(); 
+0

你能幫我理解什麼IEnumerable 和產量呢?如果沒有,我可以查看他們,我欣賞這種答案。 – 2012-04-20 19:46:59

+0

@BrokenGlass - 試試吧,它效果很棒。代碼在幕後被「提升」爲一個單獨的類,並且在枚舉之後才能達到處置。 – 2012-04-20 19:47:31

+0

@JamesWilson yield關鍵字創建了所謂的「Iterator」。這是一個知道如何遍歷某種集合的對象。 IEnumerable 是另一種描述SqlDataReader重要部分的方法。你可以在foreach(;;)循環中使用它。 – 2012-04-20 19:50:16

-1

根據定義,using語句應該它被稱爲後處置的對象。

因此,在您返回數據讀取器後,它將被處置。

+1

-1:你當然可以從'using'塊中返回! – 2012-04-20 19:52:08

+0

你在說什麼?你不需要收益。去試試吧。它可能行不通,但它肯定會編譯。 – 2012-04-20 19:54:23

0

問題是你正在創建數據庫連接在你的方法之內。

如果你要去共享數據庫資源之間的很多方法,請將SqlConnection移到這個範圍之外。

這樣你就可以從這個函數返回Reader,它會一直存在。

另外,請不要在此函數中讀取(),只是返回對象。

6

將您的連接字符串添加到app.config或web.config中的AppSettings部分。

​​3210

//函數返回SqlDataReader的結果

public SqlDataReader executeReader(string sql, SqlParameter[] parameters=null) 
    { 
     SqlConnection conn = new SqlConnection(); 
     conn.ConnectionString = GetSqlConnection(); 
     conn.Open(); 
     SqlCommand cmd = new SqlCommand(); 
     cmd.Connection = conn; 
     cmd.CommandText = sql; 
     if (parameters != null) 
     { 
      cmd.CommandType = CommandType.StoredProcedure; 
      foreach (SqlParameter p in parameters) 
      { 
       cmd.Parameters.Add(p); 
      } 
     } 
     else 
     { 
      cmd.CommandType = CommandType.Text; 
     } 
     SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection); 
     return reader; 
    } 

要使用的功能:

 string query = @"SELECT cs.Status, cs.Completed 
     FROM NC_Steps s 
     INNER JOIN NC_ClientSteps cs 
      ON cs.RecID = s.RecID 
     WHERE cs.ClientID = 162 
     AND s.RecID = @value"; 
     //you can add more parameters by adding commas 
     var parameters = new SqlParameter[] { 
      new SqlParameter("@value", RecID) 
      }; 

     SqlDataReader dr = executeReader(query, parameters); 
     while (dr.Read()) 
     { 
      //fill your controls with data 
     } 
     dr.Close();