2011-09-08 77 views
1

我需要確定由ExecuteReader返回的結果集的結構。我使用以下方法:在Ado.Net中,我可以確定結果集中的列是否可以爲空?

public List<NameAndType> ResultSetStructure(DataTable columns) 
    { 
     var ret = new List<NameAndType>(); 
     foreach (DataRow column in columns.Rows) 
     { 
      ret.Add(new NameAndType { Name = column[NameIndex].ToString(), 
              Type = column[TypeIndex].ToString() 
      }); 
     } 
     return ret; 
    } 

(SNIP)

using (SqlDataReader dr = command.ExecuteReader()) 
     { 

      var rawColumns = dr.GetSchemaTable(); 
      var columns = ResultSetStructure(rawColumns); 

這給我列名和類型,但我也想知道,如果列可以爲空,這樣我才知道這以下選項可供選擇:

decimal density = dr.GetDecimal(0); 
decimal? density = dr.IsDBNull(0) ? (decimal?)null : dr.GetDecimal(0); 

我可以做到嗎? TIA。

編輯:我剛剛發現我所需要的:

column[13].ToString() 
+1

德納裏有更容易的方式來做到這一點(新的元數據發現的DMV)。但爲什麼不只是總是假定爲無效的?如果列不是NULLable,那麼只會有條件的一邊運行。 –

+0

@Aaron Bertrand這是一個很好的策略,但問題在於您希望客戶端匹配約束,以便消費者知道他們是否可以有效地將屬性設置爲NULL。你是對的,它不是你想要在運行時決定的那種東西,你真的希望它在編譯時決定,所以在運行時檢查並不能幫助你。對於一個完全動態的東西 - 你必須假設爲空。 –

+0

@Cade我建議如果你想讓客戶端匹配,你可以設計客戶端與數據庫約束。在運行時檢查它(並在客戶端建立響應驗證)會變得非常快,非常快。 :-) –

回答

0

下面的代碼能夠完成任務:

  ret.Add(new NameAndType { Name = column[NameIndex].ToString(), 
              Type = column[TypeIndex].ToString(), 
              IsNullable = column[13].ToString().Equals("True") 
0

我想有知道列是否可爲空或不是沒有這樣的方式。你可以嘗試寫下如下所示的擴展方法:

 public static decimal GetDecimal(this SqlDataReader reader, int columnIndex) 
    {  
     if(!reader.IsDBNull(columnIndex)) 
      {  
      return reader.GetDecimal(colIndex);  
      } 
     else 
      { 
        return 0; 
     } 
     } 

希望這會有所幫助!

相關問題