开发者

NHibernate: Custom Property Accessor's Get and Set methods not being called

I'm attempting to map a database field ("LS_RECNUM") possible values of NULL, 'M' and 'F' to a property with a Gender enumeration type.

The mapping looks like this:

Map(x => x.Gender).Column("LS_GENDER").Access.Using<GenderPropertyAccessor>();

...and the GenderPropertyAccessor class looks like this:

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

开发者_Go百科  public ISetter GetSetter(Type theClass, string propertyName)
  {
    return new GenderGetterSetter(theClass.GetProperty(propertyName));
  }

  public bool CanAccessThroughReflectionOptimizer
  {
    get { return false; }
  }
}

Not being particularly familiar with reflection, I'm not at all sure that the Get and Set methods have been implemented correctly.

When I try this, I still get an error 'Can't parse F as Gender'. I've tried debugging the GenderPropertyAccessor class. The relevant line (shown above) in the mapping file is executing correctly, as is the constructor for the GenderGetterSetter class, but the Get and Set methods are never called!!!

Can anyone tell me what I might be doing wrong?


I would use an implementation of IUserType for this. Here's a good simple example. In the NullSafeGet and NullSafeSet methods you will mutate the string to an enum and back, respectively. It's also critical that your Equals implementation is correct in order for NHibernate to detect changes.

Mapping the property to use a custom user type is easy:

Map(x => x.Gender).Column("LS_GENDER").CustomType(typeof(MyUserType));
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜