1

Отображение коллекции перечислений с NHibernateОтображение коллекции перечислений с NHibernate

В частности, с использованием атрибутов для отображения.

В настоящее время у меня есть работа, сопоставляющая коллекцию, поскольку тип Int32 и NH, похоже, позаботится об этом, но это не совсем идеально.

Ошибка, которую я получаю, - «Невозможно определить тип» при попытке сопоставить коллекцию с типом перечисления, которое я пытаюсь отобразить.

Я нашел пост, который сказал, чтобы определить класс как

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

, а затем сопоставить перечисление как CEnumType, но это дает «CEnumType не отображается» или что-то подобное.

У кого-нибудь есть опыт?

Так или иначе, только простой ссылки фрагмент кода, чтобы дать пример с

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

Итак, кто получил правильные атрибуты для меня отобразить эту коллекцию перечислений, так как фактические перечислений? Было бы очень приятно, если бы они были сохранены в db как строки вместо ints, но это не совсем необходимо.

ответ

1

Так я это делаю. Вероятно, есть более простой способ, но это работает для меня.

Редактировать: извините, я упустил из виду, что вы хотите, чтобы это список. Я не знаю, как это сделать ...

Edit2: возможно, вы можете сопоставить его как защищенный IList [string] и преобразовать в public IList [EAction] так же, как я делаю с простым свойством.

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

вместо

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

попробовать

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

т.е. изменить Int32 к String

2

Вам нужно будет непосредственно сопоставить тип CEnum. В сопоставлениях XML это означало бы создание нового элемента сопоставления класса в файле сопоставлений 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> 

Чтобы сделать это с отображений атрибутов, что-то вроде этого на вершине своего класса CEnum:

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