2010-12-01 22 views
2

J'ai une propriété enum que je veux stocker et extraire de la base de données sous forme de chaîne. NHibernate est capable de stocker l'ENUM comme une chaîne, mais lève l'exception de conversion suivante lors de la récupération:La conversion a échoué lors de la conversion de la valeur varchar xxxx en int en utilisant une énumération avec NHibernate

NHibernate.ADOException: Impossible d'exécuter la requête -> System.Data.SqlClient.SqlException: La conversion a échoué lors de la conversion valeur varchar 'Pending' au type de données int.

Basé sur le poste Mapping Enumerations with NHibernate par Jeremy Miller j'ai créé la classe suivante:

public class WorkflowAction 
{ 
    public virtual ActionStatus Status { get; set; } 
} 

qui utilise cette ENUM:

public enum RequestState 
{ 
    Pending, 
    Approved, 
    Rejected 
} 

qui utilise cette classe pour se transformer en une chaîne

public class ActionStatusEnumString : NHibernate.Type.EnumStringType 
{ 
    public ActionStatusEnumString() 
     : base(typeof(ActionStatus), 50) { } 
} 

et la configuration la propriété dans mon fichier de mapping comme ceci:

<property type="Infrastructure.Enum.ActionStatusEnumString, Infrastructure" 
    name="Status" column ="status" /> 

Comme je l'ai dit cela fonctionne très bien pour enregistrer des données. Cependant, quand je veux récupérer via ce paramètre, je reçois l'exception de conversion.

return GetSession().CreateQuery(
    @"select distinct requests from WorkflowRequestInformation as requests 
    join requests.WorkflowRequestInformationActionList as actions 
    where actions.Status = :status 
.SetParameter("status", ActionStatus.Pending) 
.List<WorkflowRequestInformation>(); 

NHibernate envoie ActionStatus.Pending à la base de données comme un nombre entier. Je suppose que c'est parce que NHibernate est juste en cours d'exécution ActionStatus.Pending.ToString().

Je peux changer mon code pour l'une des options suivantes et il va travailler

// defeats the purpose of the enum 
.SetParameter("status", "Pending") 

// while this feels heavy handed 
.SetParameter("status", Enum.GetName(typeof(ActionStatus), ActionStatus.Pending)) 

Y at-il quelque chose de construit dans NHibernate que je manque qui rend cette conversion plus automatique?

Répondre

1

Pouvez-vous m'expliquer pourquoi vous avez besoin du type 'ActionStatusEnumString'? énumérations sous forme de chaînes devrait map par défaut de toute façon, tout ce que vous avez besoin est:

<property name="Status" /> 

je fais ce genre de requêtes tout le temps, les énumérations cartographiques comme des chaînes ou ints.

+0

J'ai ajouté le type 'ActionStatusEnumString' en raison de l'erreur que je recevais et l'explication de ce blog: http://codebetter.com/blogs/jeremy.miller/archive/2006/02/20/138732.aspx . Je devrais probablement revenir en arrière et le retirer et voir si juste en utilisant '.SetParameter (" status ", Enum.GetName (typeof (ActionStatus), ActionStatus.Pending))' résout mon problème. Compte tenu de la cartographie, je devine que vous n'utilisez pas couramment, non? – ahsteele

+1

Actuellement, j'utilise Fluent NHibernate. Si je veux un entier au lieu d'une chaîne, j'utilise juste Map (x => x.Status) .CustomType (); – cbp

+0

BTW. L'article que vous liez est de 2006 - beaucoup de choses ont changé depuis lors! – cbp