How do you handle Nullable type with SqlDataRecord
As @phoog recommended, extension methods for different types:
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);
}
}
}
I've never worked with SqlDataRecord
, but when using DataTable
and DataRow
, or when using parameterized queries, I specify null
using DBNull.Value
.
With SqlDataRecord
, it looks like you can use the SetDBNull
method.
Extension method:
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);
}
}
or, to use SetSqlInt32
as suggested by 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
}
}
Note, 9 Dec 2013: Returning to this answer because of a comment, I noticed a small opportunity for improvement, based on Eric Lippert's series on nullable micro-optimizations, which can be found at http://ericlippert.com/2012/12/20/nullable-micro-optimizations-part-one/.
In brief, while the Value
property requires less typing and is therefore arguably more optimal for the programmer, it has to throw an exception if HasValue is false. On the other hand, the GetValueOrDefault()
method is a simple field access. Because of this, GetValueOrDefault()
requires fewer instructions and is more likely to be inlined, so it is more optimal for the compiler and the processor.