我正在尝试将数据库字段(“LS_RECNUM”)的可能值NULL,'M'和'F'映射到具有Gender枚举类型的属性。
映射如下所示:
Map(x => x.Gender).Column("LS_GENDER").Access.Using<GenderPropertyAccessor>();
...且GenderPropertyAccessor类看起来像这样:
using System;
using System.Collections;
using System.Reflection;
using Kctc;
using NHibernate.Engine;
using NHibernate.Properties;
public class GenderPropertyAccessor : IPropertyAccessor
{
#region Setter
private class GenderGetterSetter : IGetter, ISetter
{
PropertyInfo _property;
public GenderGetterSetter(PropertyInfo property)
{
if (property == null) throw new ArgumentNullException("property");
if (property.PropertyType != typeof(Gender)) throw new ArgumentException("property");
_property = property;
}
public void Set(object target, object value) //Convert string to enum
{
_property.SetValue(target, GetGenderFromString(value), null);
}
public object Get(object target) //Convert enum back to string
{
Gender gender = (Gender)_property.GetValue(target, null);
return SetGenderToString(gender);
}
/// <summary>
/// Interprets the supplied string as a gender.
/// </summary>
/// <param name="strGender">The gender as either 'F' or 'M'.</param>
/// <returns></returns>
private Gender GetGenderFromString(object strGender)
{
if (strGender == null) return Gender.Unknown;
switch (strGender.ToString().ToLower())
{
case "f":
return Gender.Female;
case "m":
return Gender.Male;
default:
return Gender.Unknown;
}
}
/// <summary>
/// Sets the supplied Gender to the appropriate 'M' or 'F' value.
/// </summary>
/// <param name="objGender">The gender.</param>
/// <returns></returns>
private string SetGenderToString(object objGender)
{
Gender gender = (Gender) objGender;
switch (gender)
{
case Gender.Female:
return "F";
case Gender.Male:
return "M";
default:
return null;
}
}
public MethodInfo Method
{
get { return null; }
}
public string PropertyName
{
get { return _property.Name; }
}
public object GetForInsert(object owner, IDictionary mergeMap, ISessionImplementor session)
{
return Get(owner);
}
public Type ReturnType
{
get { return typeof(byte[]); }
}
}
#endregion
public IGetter GetGetter(Type theClass, string propertyName)
{
return new GenderGetterSetter(theClass.GetProperty(propertyName));
}
public ISetter GetSetter(Type theClass, string propertyName)
{
return new GenderGetterSetter(theClass.GetProperty(propertyName));
}
public bool CanAccessThroughReflectionOptimizer
{
get { return false; }
}
}
对反射不是特别熟悉,我完全不确定Get和Set方法是否已正确实现。
当我尝试这个时,我仍然会收到错误“无法将F解析为性别”。我已经尝试调试GenderPropertyAccessor类。映射文件中的相关行(如上所示)正确执行,GenderGetterSetter类的构造函数也是如此,但Get和Set方法永远不会被调用!!!
谁能告诉我自己可能做错了什么?
答案 0 :(得分:3)
我会为此使用IUserType的实现。这是一个good simple example。在NullSafeGet和NullSafeSet方法中,您将分别将字符串变为枚举和返回。为了让NHibernate检测到变化,你的Equals实现是正确的也是至关重要的。
将属性映射为使用自定义用户类型非常简单:
Map(x => x.Gender).Column("LS_GENDER").CustomType(typeof(MyUserType));