簡體   English   中英

你如何使用 SqlDataRecord 處理 Nullable 類型

[英]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 ,但是在使用DataTableDataRow ,或使用參數化查詢時,我使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM