2014-12-21 69 views
0

我想要做的是在使用datareader.GetOrdinal()時,安全地保護從IndexOutOfRangeException的C#數據檢索代碼。如果我的過程不改變,並且它們只返回一個結果集,則這沒有問題。但是,如果他們返回多個結果集,那麼我需要使用.NextResult()迭代結果集。這沒有問題。你可以有一個「強」類型的DataReader結果集嗎?

但是,如果有人改變了程序,讓另一個選擇語句,以便我的C#檢索代碼的順序改變,一切都炸了?

但問題是:我可以檢查結果是否是我想要的結果?

下面是我喜歡做的僞代碼。

using (SqlDataReader reader = cmd.ExecuteReader()) 
{ 
    //The check I would like to be able to do 
    if(reader.Result != "The result with someColumnName") 
    { 
    //This is not the result Im looking for so I try the next one 
    reader.NextResult(); 
    } 
    else //Get the result set I want.. If it blows up now it should.. 
    { 
     if (reader.HasRows) 
     { 
     //Get all ordinals first. Faster than searching with index. 
     int someColumnNameOrdinal = reader.GetOrdinal("someColumnName"); 
     while (reader.Read()) 
     { 
      var someValue = reader.GetString(someColumnNameOrdinal); 
      } 
     } 
    } 
} 

我知道,我可以嘗試GetOrdinal,得到例外,抓住它,然後嘗試下一個結果,但這只是該死的不潔(和錯誤的)。

+0

您可以調用GetSchemaTable,但可能會顯着降低代碼速度。 – Steve

+3

2014年,試圖實現什麼OR/M給你開箱...完全浪費時間 –

+0

不確定數據讀取器,但您可以將DataTable綁定到強類型模型。 –

回答

0

使用OR/M是一種很好的做法,但當然也有例外。例如,您可能會被迫查詢不支持存儲過程的SQL Server(SQL Server Compact等)。爲了提高性能,你可以選擇使用SqlDataReader。爲了確保您的字段名稱總是正確的(對應於實體類的字段),你可以使用下面的練習 - 而不是硬編碼字段名使用此代碼來代替:

GetPropertyName((YourEntityClass c) => c.YourField) 

GetPropertyName函數包含下面的代碼(仿製藥使用):

public static string GetPropertyName<T, TReturn>(System.Linq.Expressions.Expression<Func<T, TReturn>> expression) 
{ 
    System.Linq.Expressions.MemberExpression body = (System.Linq.Expressions.MemberExpression)expression.Body; 
    return body.Member.Name; 
} 

YourEntityClass是在實體框架的表中的類名,YourField在這個表中的字段名。在這種情況下,您同時具有SqlDataReader的性能和實體框架的安全性。

0

假設每個結果集都有一個唯一命名的第一列,在你的僞代碼示例如下一行:

if(reader.Result != "The result with someColumnName") 

您可以使用SqlDataReader.GetName功能檢查的第一個列的名稱。例如:

if(reader.GetName(0) != "ExpectedColumnName") 
相關問題