1

Cartographie une collection de énumérations avec NHibernateune collection de énumérations avec NHibernate

Plus précisément, en utilisant des attributs pour les correspondances.

Actuellement, j'ai cette cartographie de travail de la collection que le type Int32 et NH semble prendre soin de lui, mais ce n'est pas exactement idéal.

L'erreur que je reçois est "Impossible de déterminer le type" lorsque j'essaie de mapper la collection à partir du type de l'énumération que j'essaie de mapper.

J'ai trouvé un poste qui dit de définir une classe comme

public class CEnumType : EnumStringType { 
    public CEnumType() : base(MyEnum) { } 
} 

et la carte puis l'ENUM CEnumType, mais cela donne « CEnumType n'est pas mis en correspondance » ou quelque chose de similaire.

Alors, est-ce que quelqu'un a déjà eu cette expérience?

De toute façon, un simple extrait de code de référence pour donner un exemple avec

[NHibernate.Mapping.Attributes.Class(Table = "OurClass")] 
    public class CClass : CBaseObject 
    { 
     public enum EAction 
     { 
      do_action, 
      do_other_action 
     }; 

     private IList<EAction> m_class_actions = new List<EAction>(); 

     [NHibernate.Mapping.Attributes.Bag(0, Table = "ClassActions", Cascade="all", Fetch = CollectionFetchMode.Select, Lazy = false)] 
     [NHibernate.Mapping.Attributes.Key(1, Column = "Class_ID")] 
     [NHibernate.Mapping.Attributes.Element(2, Column = "EAction", Type = "Int32")] 
     public virtual IList<EAction> Actions 
     { 
      get { return m_class_actions; } 
      set { m_class_actions = value;} 
     } 
} 

Ainsi, tout le monde a les attributs corrects pour moi à la carte de cette collection énumérations comme énumérations réelle? Ce serait vraiment bien si elles étaient stockées dans la base de données sous forme de chaînes au lieu d'ints aussi, mais ce n'est pas tout à fait nécessaire.

Répondre

1

C'est ainsi que je le fais. Il y a probablement un moyen plus facile mais cela fonctionne pour moi. Edit: désolé, j'ai oublié que vous le voulez comme une liste. Je ne sais pas comment faire ça ...

Éditer2: peut-être vous pouvez le mapper comme IList [chaîne] protégé, et convertir en public IList [EAction] comme je le fais avec une simple propriété.

public virtual ContractGroups Group 
    { 
     get 
     { 
      if (GroupString.IsNullOrEmpty()) 
       return ContractGroups.Default; 

      return GroupString.ToEnum<ContractGroups>(); // extension method 
     } 
     set { GroupString = value.ToString(); } 
    } 

    // this is castle activerecord, you can map this property in NH mapping file as an ordinary string 
    [Property("`Group`", NotNull = true)] 
    protected virtual string GroupString 
    { 
     get; 
     set; 
    } 



    /// <summary> 
    /// Converts to an enum of type <typeparamref name="TEnum"/>. 
    /// </summary> 
    /// <typeparam name="TEnum">The type of the enum.</typeparam> 
    /// <param name="self">The self.</param> 
    /// <returns></returns> 
    /// <remarks>From <see href="http://www.mono-project.com/Rocks">Mono Rocks</see>.</remarks> 
    public static TEnum ToEnum<TEnum>(this string self) 
     where TEnum : struct, IComparable, IFormattable, IConvertible 
    { 
     Argument.SelfNotNull(self); 

     return (TEnum)Enum.Parse(typeof(TEnum), self); 
    } 
1

au lieu de

[NHibernate.Mapping.Attributes.Element(2, Column = "EAction", Type = "Int32")] 

essayer

[NHibernate.Mapping.Attributes.Element(2, Column = "EAction", Type = "String")] 

-à-dire: changer le Int32-String

2

Vous aurez besoin de mapper votre type CEnum directement. Dans les mappages XML, cela signifierait la création d'un nouvel élément de mappage de classe dans votre fichier de mappage XML NHibernate.

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="YourAssembly" 
    auto-import="true" default-lazy="false"> 

    ... 

    <class name="YourAssemblyNamespace.CEnum" table="CEnumTable" mutable="false" > 
     <id name="Id" unsaved-value="0" column="id"> 
     <generator class="native"/> 
     </id> 

     ... 

    </class> 

</hibernate-mapping> 

Pour ce faire avec les correspondances d'attributs, quelque chose comme ceci sur le dessus de votre classe CENUM:

[NHibernate.Mapping.Attributes.Class(Table = "CEnumTable")] //etc as you require

Questions connexes