Отображение коллекции перечислений с помощью NHibernate - PullRequest
1 голос
/ 17 сентября 2008

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

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

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

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

Я нашел сообщение, в котором говорится, что класс определяется как

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

и затем сопоставьте enum как CEnumType, но это дает "CEnumType not mapped" или что-то подобное.

Так у кого-нибудь есть опыт в этом?

Так или иначе, просто фрагмент справочного кода для примера с

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

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

Ответы [ 4 ]

2 голосов
/ 11 мая 2010

Вам нужно будет напрямую сопоставить ваш тип CEnum. В сопоставлениях XML это будет означать создание нового элемента сопоставления классов в файле сопоставлений NHibernate XML.

<pre></p> <pre><code><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

1 голос
/ 18 октября 2008

вместо

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

попробовать

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

т.е.: изменить Int32 на String

1 голос
/ 07 ноября 2008

Хотя я сам не пробовал использовать его, я наткнулся на этот код некоторое время назад, и он выглядит довольно интересно:

http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/08/12/enumeration-classes.aspx

Как я уже сказал, я не использовал его сам, но собираюсь попробовать его в проекте RSN.

1 голос
/ 17 сентября 2008

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

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

Edit2: возможно, вы можете отобразить его как защищенный IList [string] и преобразовать в публичный 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);
    }
...