質問

これはhibernate.orgフォーラムとnhusersリストにあまり運がなかったので、ここで試してみようと思いました。

簡単に言えば、クラスがあるとします:

class A
{
   public virtual object SomeValue { get; set; }
}

SomeValueの型は、基本的に.NET IConvertible型(bool、byte、char、int16、double、floatなどのプリミティブ)に加えて、byte []と文字列のセットにあります。

これを反映するためにAのnhibernateマッピングを作成しようとしています-基本的にSomeValueを(上記のタイプの)任意のオブジェクトに設定し、後で取得できるようにするためです。その後、applogicはそれを反映してタイプを見つけ、それに応じて動作します。

これまでのところ、これを処理しようとするIUserTypeの実装を作成しようとしました。ただし、SqlType [] SqlTypesに対して何を返すかわかりません。新しいSqlType(DbType.Object)を検討しましたが、これからスキーマを生成しようとすると、System.ArgumentExceptionが表示されます。DialectはDbType.Objectをサポートしていません

別のデータ型を試すと、型を変換しようとしたときにさまざまなキャスト例外が発生します。たとえば、DbType.Binaryを使用し、someValueをint32に設定すると、コミットしようとするとSystem.InvalidCastExceptionが発生します。タイプ 'System.Int32'のオブジェクトをタイプ 'System.Byte []'にキャストできません。

これを達成する方法はありますか?

IUserTypeの非動作実装用の以下の添付コード(

役に立ちましたか?

解決

Sqlect(DbType.Object)がDialectでサポートされていないという問題を回避することが判明しました。明示的なサポートでSQLiteDialectをサブクラス化することでサポートします:

public class SQLiteDialectWithManifestTyping : SQLiteDialect
{
    public SQLiteDialectWithManifestTyping() : base()
    {
        base.RegisterColumnType(DbType.Object, "NONE");
    }
}

Fluentでこの方言を使用するには、SQLiteConfigurationオブジェクトでDialect()を呼び出します。 NHibernateで、構成プロパティの方言を適切に設定します(リファレンスマニュアルのセクション3.5.1を参照)。

その後、上記のDataElementType実装をマッピングに適用できます(SqlTypes定義をこれに変更する必要があります:

    public SqlType[] SqlTypes
    {
        get
        {
            return new[] { new SqlType(DbType.Object) };
        }
    }

注:

  1. 完全ではありません。すべての離散数をInt64にアップキャストし、浮動小数点数を2倍にする傾向があります。

  2. 大きな符号なしの値(ulong> = long.MaxValueの値など)を暗黙的に保存する方法はありませんが、これは一般的なsqliteの問題です(そして、一般的なado.netの問題ですか?)。

  3. コンパイル時のチェックが失われるため、値がプリミティブ型であることを確認するために、NullSafeSetメソッドにランタイムチェックを行うことが望ましい場合があります。一般的なオブジェクトを保存しようとすると、オブジェクトのToString()メソッドが呼び出されるだけのようです。

scroll top