2010-11-19 24 views
2

NULL、 'M'、および 'F'のデータベースフィールド( "LS_RECNUM")に可能な値をGender列挙型のプロパティにマップしようとしています。NHibernate:カスタムプロパティアクセサのGetメソッドとSetメソッドが呼び出されない

マッピングは次のようになります。

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メソッドは決して呼び出されません。

私は間違っていると誰に教えてもらえますか?

答えて

3

私はこのためにIUserTypeの実装を使用します。ここにはgood simple exampleがあります。 NullSafeGetメソッドとNullSafeSetメソッドでは、文字列をそれぞれ列挙型と背部型に変更します。 NHibernateが変更を検出するためには、Equals実装が正しいことも重要です。

カスタム・ユーザー・タイプを使用するようにプロパティのマッピングは簡単です:

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

ジェイミー、これは正しく性別列挙型に「F」/「M」に変換し、私はLINQのを使用して性別プロパティに照会するとき私はこれを取得します:NHibernate.Criterion.SimpleExpressionで型の不一致が発生しました。死んだ.Gender予想型Kctc.NHibernate.Lawbase.UserTypes.GenderUserType、実際の型Kctc.Gender – David

+0

これは機能しますか?私はそれを間違ってしまった? – David

+0

謝罪します。 Typeof(Gender)ではなくTypeof(MyUserType)を返すようにReturnedTypeを設定しました。これを修正し、美しく動作します!私の日に小さな星屑を散らしてくれてありがとう。 – David

関連する問題