4

私は一方の側にAccessデータベースを持っています。ここで、Tbl_Application.id_connexionはタイプのフィールドですGuid(msAccessの用語では「レプリケーションID」と呼ばれます)。

このTbl_ApplicationテーブルからDataRow[]配列を介していくつかのデータを収集していますdr_Tbl_Application。次のコードは、最初のDataRowを読み取ります。

private Guid? mid_connexion = null;
mid_connexion = (Guid)dr_Tbl_Application[0]["id_connexion"]

Tbl_Application.id_connexion値を保持している限り、すべてがOKです。このフィールドに値が含まれていない場合、次のエラーが発生します。

InvalidCastException was unhandled

そして、これらは私がすぐに見ることができるいくつかのものです:

? dr_Programme[0]["id_Connexion"]
{}

? dr_Programme[0]["id_Connexion"].GetType()
{Name = "DBNull" FullName = "System.DBNull"}

? dr_Programme[0]["id_Connexion"] is System.DBNull
true

したがって、例外を回避するために、データベースのフィールドからローカル変数に一意の識別子の値を転送する前にテストする方がよいと思います。そうは言っても、私はまだ自分の発見に悩まされているので、この問題をさらに深く掘り下げたいと思います。

私の質問は次のとおりです。

  1. テストせずに、データベースのGuid値からローカルのGuidオブジェクトに値を割り当てるための基本的なコードを作成する方法はありますSystem.DBNullか?
  2. 元のフィールドが値を保持しているかどうかに応じて、同じオブジェクトに適用された同じ命令が異なる型を返す必要があるのはなぜですか?

質問2で編集:

? dr_Programme[0]["id_Connexion"].GetType()

対応するフィールドが元のテーブルに入力されている場合、System.Guidタイプを返します。

? dr_Programme[0]["id_Connexion"].GetType()

元のテーブルでフィールドがnull(または入力されていない)の場合、System.DBNullタイプを返します...

4

3 に答える 3

4

DBNullNULLを返すDBと何も返さないDBの違いに対処するために、 Nullオブジェクトデザインパターンを実装します。残念ながら、その直感性の欠如は、長年にわたってプログラマーをつまずかせ続けています。

あなたができる最善のことは、次のような一般的なメソッドでラップすることです。

public static T? GetNullable<T>(object obj) where T : struct
{
    if (obj == DBNull.Value) return null;
    return (T?)obj;
}

これで、このメソッドを次のように呼び出すことができます。

mid_connexion = GetNullable<Guid>(dr_Tbl_Application[0]["id_connexion"]);
于 2012-12-28T12:58:12.380 に答える
1

DBスキーマが発生しないように設計しない限り、DBNullをチェックし続ける必要があります。また、DBNullはC#nullとは異なることに注意してください。

C#でConvertクラスを使用すると、コードの冗長性を少し減らすことができます。一般に、例外をスローするのではなく、デフォルトの変換を実行します(たとえば、null値が検出された場合、DBNull値の処理方法がわからないため、手動で処理する必要があることに注意してください)。

私の推奨事項は、必要な作業を行うための一連の拡張メソッドを作成することです。

public static class AccessExtensions
{
    public static Guid GetGuidOrEmpty( this IDbReader reader, string columnName )
    {
        // all the code to check for DBNull and conversions goes here
        // ...

        return hasValue ? value : Guid.Empty;
    }
}

最後の注意点は、挿入/更新に文字列を要求するが、選択時にGUIDタイプを返すなど、AccessがGUIDについておかしい場合があることです。2003年頃に試したので改善したかもしれません。

于 2012-12-28T12:55:44.840 に答える
1

これを使って:

public static class SomeClass
    {
        public static Guid? With(this Guid? o, object x)
        {
            if (x is System.DBNull) return null;
            return o = (Guid)x;
        }
    }
于 2012-12-28T13:12:21.893 に答える