2011-12-06 47 views
8

我正在解析XML(LINQ to XML),並且在元素/屬性爲空的情況下我使用可空類型(int?decimal?)。但是,當構建我的集合傳遞給數據庫(使用TVP)時,我不知道如何處理值實際上爲null的情況。我不能將null傳遞給SqlDataRecord SetInt32或SetDecimal,我不想將其設置爲零....我實際上希望它爲null。如何處理SqlDataRecord的Nullable類型

告訴我沒有超載int?下面

計數是可空類型(int?計數)

SqlDataRecord rec = new SqlDataRecord(
       new SqlMetaData("Name", SqlDbType.VarChar, 50), 
       new SqlMetaData("Type", SqlDbType.VarChar, 50), 
       new SqlMetaData("Count", SqlDbType.Int)); 

    rec.SetString(0, dm.Name); 
    rec.SetString(1, dm.Type); 
    rec.SetString(2, dm.Count); 

任何想法如何處理這個問題沒有通過零(保持空)?

回答

10

擴展方法:

static class SqlDataRecordExtensions 
{ 
    static void SetNullableInt32(this SqlDataRecord rec, int index, Int32? value) 
    { 
     if (value.HasValue) 
      rec.SetInt32(index, value.GetValueOrDefault()); 
     else 
      rec.SetDBNull(index); 
    } 
} 

,或者使用SetSqlInt32由d士丹利的建議:

static class SqlDataRecordExtensions 
{ 
    static void SetNullableInt32(this SqlDataRecord rec, int index, Int32? value) 
    { 
     rec.SetSqlInt32(index, value.HasValue ? value.GetValueOrDefault() : SqlInt32.Null); 
     //          ^^^^^^^^^^^^^^^^^^^^^^^^^ 
     //          You can leave out the cast to (SqlInt32), 
     //          because the conversion is implicit 
    } 
} 

注意,2013年12月9日:因爲註釋的返回這個答案,我注意到一個小改進的機會,基於Eric Lippert關於可空微優化的系列,可以在http://ericlippert.com/2012/12/20/nullable-micro-optimizations-part-one/找到。

簡而言之,雖然Value屬性需要較少的鍵入,因此可以說程序員更適合,但如果HasValue爲false,它必須引發異常。另一方面,GetValueOrDefault()方法是一個簡單的字段訪問。正因爲如此,GetValueOrDefault()需要更少的指令,並且更可能被內聯,所以它對於編譯器和處理器來說更爲理想。

+0

+1,非常好.. –

+0

SetValue(ordinal,object)處理可空和空值對於類型和類型有一點點的開銷值長度檢查。性能差異可能不明顯。 –

+0

@RichardCollette感謝您的評論;我沒有想到這一點。我懷疑你是對的,大多數應用程序的性能差異可能是微不足道的。不過,我確實傾向於更喜歡以哲學爲理由的更強大的打字。您的評論也激勵我添加兩年前沒有想到的小型優化。 – phoog

3

我從來沒有與SqlDataRecord,只是用DataTableDataRow時,或使用參數化查詢的時候,我用DBNull.Value指定null

SqlDataRecord,它看起來像你可以使用SetDBNull方法。

0

應該使用SetSqlInt32而不是SetString。嘗試

rec.SetSqlInt32(2, (dm.Count.HasValue ? new SqlInt32(dm.Count) : SqlInt32.Null)); 
+0

這必須是值'rec.SetSqlInt32(2,(dm.Count.HasValue?new SqlInt32(dm.Count.Value):SqlInt32.Null));' – phoog

+0

此外,當我編輯我的答案時意識到,從int到SqlInt32的隱式轉換意味着你可以這樣做:'rec.SetSqlInt32(2,dm.Count.HasValue?dm.Count.Value:SqlInt32.Null);' – phoog

0

//香港專業教育學院發現這檢查或處理可空類型時,工作最適合我 //在我的例子,我檢查存儲在一個String []數組

sqlcmdUpdateRecord.Parameters.AddWithValue("@strSomeValue", (strRecord[(int) 
DataFields.SomeDataField] as object) ?? DBNull.Value);