我想使用来自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时,引发异常。
你能想到优雅的解决方案吗?
答案 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
我想做一些更优雅的事情来从读者那里获得“真正的”数据类型。