VB.NET 2010和MySql - 为懒人处理DB NULL

时间:2010-07-28 07:57:36

标签: mysql sqldatareader dbnull vb.net-2010

我想使用来自MySql数据库的数据初始化一个类。某些字段可以为null:

Dim dr As MySqlDataReader = ...
Dim item As New Item(dr.GetInt16(0), dr.GetString(1), dr.GetString(2))

假设最后两个字段可能为NULL在db中,因此在该字段上调用GetString会导致异常。

在获取每个字段之前,我当然可以编写代码来测试NULL:

dim field1 as String 
if ( dr.IsDbNull(1) )
   field1 = Nothing                  ' or even ""
else
   field1 = dr.GetString(1)

但是如果你有很多领域,这就是“ifs”的噩梦。

为此,我重写了IIf VB函数以使其更加类型化,从而避免强制转换:

Namespace Util

Public Shared Function IIf(Of T)(ByVal condition As Boolean, ByVal iftrue As T, ByVal iffalse As T) As T
        If condition Then Return iftrue Else Return iffalse
End Function

这样我就能写出类似的内容:

Dim item As New Item(
     dr.GetInt16(0), 
     Util.IIf(dr.IsDbNull(1), "", dr.GetString(1), 
     Util.IIf(dr.IsDbNull(2), "", dr.GetString(2))

键入的 IIf 在其他情况下运行良好,但遗憾的是在这种情况下不会,因为是正常函数而不是语言关键字,每个inpout在调用期间计算参数,当字段为NULL时,引发异常。

你能想到优雅的解决方案吗?

2 个答案:

答案 0 :(得分:0)

首先,我建议您使用ORM映射器 - 现在很少有情况需要手动“映射”。

如果这是其中一种情况,我建议您在访问数据阅读器时使用字段名称而不是索引。

并回答您的原始问题:尝试扩展方法。对不起C#,但VB.NET语法让我疯狂:

public static class DbDataReaderExtensions
{
    public static T GetField<T>(this DbDataReader dbDataReader, string fieldName, 
        T defaultValue)
    {
        if(dbDataReader.IsDBNull(fieldName))
            return defaultValue;
        return (T)dbDataReader[fieldName];
    }
}

答案 1 :(得分:0)

感谢。

我查看了很多ORM,但由于某种原因我不喜欢它们,所以我决定调用普通的存储过程来获取数据。你能建议一些强大而简单的东西吗?

你是正确的使用字段名称,它更安全,即使有点慢。

我刚用方法得出了相同的结论,但我仍然不喜欢的是类型转换:

Public Shared Function IfNull(Of T)(ByVal dr As MySqlDataReader, ByVal index As Integer, ByVal _default As T) As T
        If dr.IsDBNull(index) Then
            Return _default
        Else
            Return CType(dr.GetValue(index), T)
        End If

End Function

我想做一些更优雅的事情来从读者那里获得“真正的”数据类型。