[英]How do you handle Nullable type with SqlDataRecord
我正在解析 XML(LINQ to XML),並且在元素/屬性為空的情況下使用可空類型( int?
和decimal?
)。 但是,在構建我的集合以傳遞給數據庫(使用 TVP)時,我不知道如何處理值實際上為 null 的情況。 我不能將空值傳遞到 SqlDataRecord SetInt32 或 SetDecimal 中,我不想設置為零......我實際上希望它為空。
告訴我int
沒有過載?
下面的 Count 是可空類型( int?
Count )
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);
任何想法如何在不傳遞零(保持空值)的情況下處理這個問題?
擴展方法:
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);
}
}
或者,按照 D Stanley 的建議使用SetSqlInt32
:
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()
需要更少的指令並且更有可能被內聯,因此它對於編譯器和處理器來說更優化。
我從未使用過SqlDataRecord
,但是在使用DataTable
和DataRow
,或使用參數化查詢時,我使用DBNull.Value
指定null
。
使用SqlDataRecord
,您似乎可以使用SetDBNull
方法。
正如@phoog 所推薦的,不同類型的擴展方法:
public static class ExtensionSqlDataRecord
{
public static void SetDateTime(this SqlDataRecord record, int ordinal, DateTime? value)
{
if (value != null)
{
record.SetDateTime(ordinal, (DateTime)value);
}
else
{
record.SetDBNull(ordinal);
}
}
public static void SetInt32(this SqlDataRecord record, int ordinal, int? value)
{
if (value != null)
{
record.SetInt32(ordinal, (int)value);
}
else
{
record.SetDBNull(ordinal);
}
}
public static void SetByte(this SqlDataRecord record, int ordinal, byte? value)
{
if (value != null)
{
record.SetByte(ordinal, (byte)value);
}
else
{
record.SetDBNull(ordinal);
}
}
public static void SetDecimal(this SqlDataRecord record, int ordinal, decimal? value)
{
if (value != null)
{
record.SetDecimal(ordinal, (decimal)value);
}
else
{
record.SetDBNull(ordinal);
}
}
public static void SetBoolean(this SqlDataRecord record, int ordinal, bool? value)
{
if (value != null)
{
record.SetBoolean(ordinal, (bool)value);
}
else
{
record.SetDBNull(ordinal);
}
}
}
也許你可以試試下面的。
if(dm.Count == null){
rec.SetDBNull(2)
}
else{
rec.SetString(2, dm.Count);
}
應該使用SetSqlInt32
而不是SetString
。 嘗試
rec.SetSqlInt32(2, (dm.Count.HasValue ? new SqlInt32(dm.Count) : SqlInt32.Null) );
//我發現這在檢查或處理可為空類型時最適合我 //在我的示例中,我正在檢查存儲在 String[] 數組中的值
sqlcmdUpdateRecord.Parameters.AddWithValue("@strSomeValue", (strRecord[(int)
DataFields.SomeDataField] as object) ?? DBNull.Value);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.