0

複数のシステムからアクセスされるデータベースがあります。私たちのものは、Fluent Nhibernate と Automapping を使用してテーブルを読み取ります。

列の 1 つは、列挙型を表す文字列です。ほとんどのインストールではこれで問題ありませんが、別のシステムで無効な値が保持されることがあります。これらの無効な値をキャッチして、変換または無視するにはどうすればよいですか?

例:

Database Table:
ID  MyEnum
0   "One"
1   "Two"
2   "Invalid"

MyEnum
{
  One,
  Two
}

私はすでにIAutoMappingOverride自分のモデルで使用していますが、マッパーに関数を渡して検証/変換を行う方法はありますか (未知数を に変換したいとしますMyEnum.One)? または、私が見逃しているより簡単な方法はありますか?

私がたどり着いたのは、 @ Firoの回答ここここの回答の組み合わせを使用することでした

class SafeEnumType<T> : ImmutableUserType where T : struct
{
    public override object NullSafeGet(IDataReader rs, string[] names, object owner)
    {
        T value;
        if (Enum.TryParse((string)rs[names[0]], out value))
            return value;
        else
            return default(T);
    }

    public override void NullSafeSet(IDbCommand cmd, object value, int index)
    {
        NHibernateUtil.String.NullSafeSet(cmd, value.ToString(), index);
    }

    public override Type ReturnedType
    {
        get { return typeof(T); }
    }

    public override SqlType[] SqlTypes
    {
        get { return new[] { SqlTypeFactory.GetString(100) }; }
    }
}

と追加

mapping.Map(x => x.Type).CustomType(typeof(SafeEnumType<EventType>));

私のAutomapOverride.Override()fnへ

4

1 に答える 1

1

NHibernate には、カスタム変換コードを定義できる IUserType があります。列挙型は不変型であるため、これを使用できる私の基本クラスを次に示します

コード

class SpecialEnumUserType : ImmutableUserType
{
    public override object NullSafeGet(IDataReader rs, string[] names, object owner)
    {
        TheSpecialEnum value;
        if (Enum.TryParse<TheSpecialEnum>((string)rs[names[0]], out value))
            return value;
        else
            return default(TheSpecialEnum);
    }

    public override void NullSafeSet(IDbCommand cmd, object value, int index)
    {
        NHibernateUtil.String.NullSafeSet(cmd, value.ToString(), index);
    }

    public override Type ReturnedType
    {
        get { return typeof(TheSpecialEnum); }
    }

    public override SqlType[] SqlTypes
    {
        get { return new[] { SqlTypeFactory.GetString(50) }; }
    }
}

それらをすべての列挙型プロパティに適用する規則

class EnumHandlingConvention : IPropertyConvention
{
    public void Apply(IPropertyInstance instance)
    {
        if (instance.Type == typeof(TheSpecialEnum))
        {
            instance.CustomType<SpecialEnumUserType>();
        }
    }
}
于 2013-10-14T05:51:24.300 に答える