验证或覆盖 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
在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>();
}
}
}