1

MySqlデータベースからのデータでクラスを初期化したい。一部のフィールドはnullになる可能性があります。

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

db内の最後の2つのフィールドがNULLである可能性があるため、そのフィールドで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の場合は例外が発生します。 。

エレガントなif-lessソリューションを思いつくことができますか?

4

2 に答える 2

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

リーダーから「実際の」データ型を取得するために、よりエレガントな方法を実行したいと思います。

于 2010-07-28T09:11:19.840 に答える
0

まず、ORM マッパーを使用することをお勧めします。現在、手動で「マッピング」を行う必要があるケースはほとんどありません。

これがこれらのケースの 1 つである場合は、Data Reader にアクセスする際にインデックスの代わりにフィールド名を使用することをお勧めします。

元の質問に答えるには、拡張メソッドを試してください。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];
    }
}
于 2010-07-28T08:11:10.253 に答える