我有一个可由多个系统访问的数据库。我们使用Fluent Nhibernate和Automapping读取表格。
其中一列是表示枚举的字符串。在大多数安装中,这很好,但是偶尔会有另一个系统持久存在无效值。如何捕获这些无效值并转换或忽略它们?
示例:
Database Table:
ID MyEnum
0 "One"
1 "Two"
2 "Invalid"
MyEnum
{
One,
Two
}
我已经在我的模型中使用了IAutoMappingOverride
,无论如何将函数传递给映射器进行验证/转换(比方说我想将任何未知数转换为MyEnum.One
)?
还是有一种我想念的简单方法?
我所使用的是@Firo's answer和答案here和here
的组合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
答案 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>();
}
}
}