Как вы обрабатываете обнуляемый тип с SqlDataRecord - PullRequest
9 голосов
/ 06 декабря 2011

Я анализирую XML (LINQ to XML) и использую обнуляемый тип (int? и decimal?) в тех случаях, когда элемент / атрибут пуст.Однако при построении моей коллекции для передачи в БД (с использованием TVP) я не знаю, как обращаться со случаями, когда значение на самом деле равно нулю.Я не могу передать ноль в SqlDataRecord SetInt32 или SetDecimal, и я не хочу устанавливать в ноль .... Я на самом деле хочу, чтобы он был нулевым.

Не говорите мне перегрузки для 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);

Любые идеи, как справиться с этим, не передавая ноль (поддерживая ноль)?

Ответы [ 5 ]

12 голосов
/ 06 декабря 2011

Метод расширения:

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 Stanley:

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
    }
}

Примечание, 9 декабря 2013 г .: Возвращаясь к этому ответу из-за комментария, я заметил небольшую возможность для улучшения, основанную на серии Эрика Липперта об обнуляемых микрооптимизациях, которую можно найти по адресу http://ericlippert.com/2012/12/20/nullable-micro-optimizations-part-one/.

Вкратце, хотя свойство Value требует меньше ввода и поэтому, возможно, более оптимально для программиста, оно должно выдавать исключение, если HasValue имеет значение false. С другой стороны, метод GetValueOrDefault() является простым полевым доступом. Из-за этого GetValueOrDefault() требует меньше инструкций и, скорее всего, будет встроенным, поэтому он более оптимален для компилятора и процессора.

3 голосов
/ 06 декабря 2011

Я никогда не работал с SqlDataRecord, но при использовании DataTable и DataRow или при параметризованных запросах я указываю null, используя DBNull.Value.

С SqlDataRecord похоже, что вы можете использовать метод SetDBNull.

0 голосов
/ 25 января 2019

может быть, вы можете попробовать ниже.

if(dm.Count == null){
  rec.SetDBNull(2)
}
else{
 rec.SetString(2, dm.Count);
}
0 голосов
/ 06 декабря 2011

// Я нашел, что это работает лучше всего при проверке или работе с обнуляемыми типами // в моем примере я проверяю значения, хранящиеся в массиве String []

sqlcmdUpdateRecord.Parameters.AddWithValue("@strSomeValue", (strRecord[(int) 
DataFields.SomeDataField] as object) ?? DBNull.Value);
0 голосов
/ 06 декабря 2011

Следует использовать SetSqlInt32 вместо SetString.Попробуйте

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