2008-09-09 96 views
8

因此,我使用IDataReader來保存一些業務對象,但我不知道在運行時確切地說明了讀取器中的字段。任何不在閱讀器中的字段將在結果對象上留空。你如何測試一個閱讀器是否包含一個特定的字段,而不僅僅是將其封裝在try/catch中?在迭代之前檢測IDataReader是否包含某個字段

回答

-4

您不能僅僅測試reader [「field」]爲null或DBNull,因爲如果該列不在讀取器中,則拋出IndexOutOfRangeException。

我在映射圖層中用於創建域對象的代碼和使用映射圖層的存儲過程在下面可能有不同的列名;如果未找到該列並且返回缺省值(t)或null,則可以將其修改爲不引發異常。

我知道這不是最優雅的或最佳的解決方案(如果你能避免它,那麼你應該),但是,遺留存儲過程或Sql查詢可能需要解決。

/// <summary> 
    /// Grabs the value from a specific datareader for a list of column names. 
    /// </summary> 
    /// <typeparam name="T">Type of the value.</typeparam> 
    /// <param name="reader">Reader to grab data off of.</param> 
    /// <param name="columnNames">Column names that should be interrogated.</param> 
    /// <returns>Value from the first correct column name or an exception if none of the columns exist.</returns> 
    public static T GetColumnValue<T>(IDataReader reader, params string[] columnNames) 
    { 
     bool foundValue = false; 
     T value = default(T); 
     IndexOutOfRangeException lastException = null; 

     foreach (string columnName in columnNames) 
     { 
      try 
      { 
       int ordinal = reader.GetOrdinal(columnName); 
       value = (T)reader.GetValue(ordinal); 
       foundValue = true; 
      } 
      catch (IndexOutOfRangeException ex) 
      { 
       lastException = ex; 
      } 
     } 

     if (!foundValue) 
     { 
      string message = string.Format("Column(s) {0} could not be not found.", 
       string.Join(", ", columnNames)); 

      throw new IndexOutOfRangeException(message, lastException); 
     } 

     return value; 
    } 
+1

這將表現不佳 – DalSoft 2012-07-24 18:25:53

-3

雖然我不同意這種方法(我認爲在訪問數據時,應該事先知道形狀),但我知道有例外。

您可以隨時在閱讀器中加載數據表,然後遍歷它。然後您可以檢查該列是否存在。這個性能會更差,但是你不需要try/catch塊(所以也許它會更好地滿足你的需求)。

9

這應該做的伎倆:

Public Shared Function ReaderContainsColumn(ByVal reader As IDataReader, ByVal name As String) As Boolean 
     For i As Integer = 0 To reader.FieldCount - 1 
      If reader.GetName(i).Equals(name, StringComparison.CurrentCultureIgnoreCase) Then Return True 
     Next 
     Return False 
    End Function 

或(在C#)

public static bool ReaderContainsColumn(IDataReader reader, string name) 
{ 
    for (int i = 0; i < reader.FieldCount; i++) { 
     if (reader.GetName(i).Equals(name, StringComparison.CurrentCultureIgnoreCase)) return true; 
    } 
    return false; 
} 

:O)

0

我用過的最好的解決辦法是做這樣的:

DataTable dataTable = new DataTable(); 
dataTable.Load(reader); 
foreach (var item in dataTable.Rows) 
{ 
    bool columnExists = item.Table.Columns.Contains("ColumnName"); 
} 

試圖通過讀者[「的ColumnName」]訪問它,並檢查空或爲DBNull將拋出一個例外。

4
Enumerable.Range(0, reader.FieldCount).Any(i => reader.GetName(i) == "ColumnName") 
相關問題