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

本文关键字:枚举 映射 数据库 覆盖 FluentNhibernate 验证 | 更新日期: 2023-09-27 18:35:23

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

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

例:

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

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

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