To evaluate database fields to determine whether their values are DBNull, you can pass the field value to the DBNull. Value. Equals method. However, this method is rarely used because there are a number of other ways to evaluate a database field for missing data.
Empty; Please do not confuse the notion of null in C# language with a DBNull object. In an object-oriented programming language, null means the absence of a reference to an object, whereas DBNull represents an uninitialized field or nonexistent database column.
I must be missing something. Isn't checking for DBNull
exactly what the DataRow.IsNull
method does?
I've been using the following two extension methods:
public static T? GetValue<T>(this DataRow row, string columnName) where T : struct
{
if (row.IsNull(columnName))
return null;
return row[columnName] as T?;
}
public static string GetText(this DataRow row, string columnName)
{
if (row.IsNull(columnName))
return string.Empty;
return row[columnName] as string ?? string.Empty;
}
Usage:
int? id = row.GetValue<int>("Id");
string name = row.GetText("Name");
double? price = row.GetValue<double>("Price");
If you didn't want Nullable<T>
return values for GetValue<T>
, you could easily return default(T)
or some other option instead.
On an unrelated note, here's a VB.NET alternative to Stevo3000's suggestion:
oSomeObject.IntMember = If(TryConvert(Of Integer)(oRow("Value")), iDefault)
oSomeObject.StringMember = If(TryCast(oRow("Name"), String), sDefault)
Function TryConvert(Of T As Structure)(ByVal obj As Object) As T?
If TypeOf obj Is T Then
Return New T?(DirectCast(obj, T))
Else
Return Nothing
End If
End Function
You should use the method:
Convert.IsDBNull()
Considering it's built-in to the Framework, I would expect this to be the most efficient.
I'd suggest something along the lines of:
int? myValue = (Convert.IsDBNull(row["column"]) ? null : (int?) Convert.ToInt32(row["column"]));
And yes, the compiler should cache it for you.
The compiler won't optimise away the indexer (i.e. if you use row["value"] twice), so yes it is slightly quicker to do:
object value = row["value"];
and then use value twice; using .GetType() risks issues if it is null...
DBNull.Value
is actually a singleton, so to add a 4th option - you could perhaps use ReferenceEquals - but in reality, I think you're worrying too much here... I don't think the speed different between "is", "==" etc is going to be the cause of any performance problem you are seeing. Profile your entire code and focus on something that matters... it won't be this.
I would use the following code in C# (VB.NET is not as simple).
The code assigns the value if it is not null/DBNull, otherwise it asigns the default which could be set to the LHS value allowing the compiler to ignore the assign.
oSomeObject.IntMemeber = oRow["Value"] as int? ?? iDefault;
oSomeObject.StringMember = oRow["Name"] as string ?? sDefault;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With