验证或覆盖FluentNhibernate数据库到枚举映射

时间:2013-10-14 01:05:23

标签: c# .net enums fluent-nhibernate

我有一个可由多个系统访问的数据库。我们使用Fluent Nhibernate和Automapping读取表格。

其中一列是表示枚举的字符串。在大多数安装中,这很好,但是偶尔会有另一个系统持久存在无效值。如何捕获这些无效值并转换或忽略它们?

示例:

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

MyEnum
{
  One,
  Two
}

我已经在我的模型中使用了IAutoMappingOverride,无论如何将函数传递给映射器进行验证/转换(比方说我想将任何未知数转换为MyEnum.One)? 还是有一种我想念的简单方法?

我所使用的是@Firo's answer和答案herehere

的组合
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

1 个答案:

答案 0 :(得分:1)

在NHibernate中有IUserType,它允许您定义自定义转换代码。 here是我的基类,你可以使用它,因为枚举是不可变类型

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>();
        }
    }
}