Je tente de mapper un champ de base de données ("LS_RECNUM") valeurs possibles de NULL, 'M' et 'F' à une propriété avec un type d'énumération de genre.NHibernate: Les méthodes Get et Set de l'accesseur de propriétés personnalisées ne sont pas appelées
La cartographie ressemble à ceci:
Map(x => x.Gender).Column("LS_GENDER").Access.Using<GenderPropertyAccessor>();
... et la classe GenderPropertyAccessor ressemble à ceci:
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; }
}
}
Ne pas être particulièrement familier avec la réflexion, je ne suis pas du tout sûr que les méthodes Get et Set ont été implémentées correctement.
Lorsque j'essaie cela, j'obtiens toujours une erreur 'Impossible d'analyser F en fonction du sexe'. J'ai essayé de déboguer la classe GenderPropertyAccessor. La ligne correspondante (illustrée ci-dessus) dans le fichier de mapping s'exécute correctement, tout comme le constructeur de la classe GenderGetterSetter, mais les méthodes Get et Set ne sont jamais appelées !!! Est-ce que quelqu'un peut me dire ce que je pourrais faire de mal?
Jamie, ce convertit le « F »/« M » correctement dans le ENUM de genre, mais quand je fais une recherche sur la propriété Sexe LINQ Je reçois ceci: Type incompatibilité dans NHibernate.Criterion.SimpleExpression: Deceased.Gender attendu type Kctc.NHibernate.Lawbase.UserTypes.GenderUserType, type réel Kctc.Gender – David
Si cela a fonctionné? Est-ce que je l'ai fait mal? – David
Mes excuses. Je définis ReturnedType pour renvoyer typeof (MyUserType) plutôt que typeof (Gender). Fixé ceci maintenant, et cela fonctionne magnifiquement! Merci d'avoir saupoudré un peu de poussière d'étoile dans ma journée. – David