使用NHibernate映射枚举集合

时间:2008-09-17 01:11:21

标签: nhibernate collections enums attributes nhibernate-mapping

使用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;}
        }
}

那么,任何人都有正确的属性让我将这个枚举集合映射为实际的枚举?如果它们作为字符串而不是整数存储在数据库中,那将是非常好的,但它并不是完全必要的。

4 个答案:

答案 0 :(得分:2)

您需要直接映射您的CEnum类型。在XML映射中,这意味着在NHibernate XML映射文件中创建一个新的类映射元素。

<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类之上一样:

<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>

答案 1 :(得分:1)

这就是我这样做的方式。这可能是一种更简单的方法,但这对我有用。

编辑:对不起,我忽略了你想要它作为一个列表。我不知道该怎么做......

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

答案 2 :(得分:1)

而不是

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

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

即:将Int32更改为String

答案 3 :(得分:1)

虽然我自己没有尝试过使用它,但是我前一段时间偶然发现了这段代码,看起来非常有趣:

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

就像我说的那样,我自己没有使用它,但我会在RSN项目中试一试。