使用 Fluent NHibernate 和 NHibernate 3 将枚举映射为 Int

Posted

技术标签:

【中文标题】使用 Fluent NHibernate 和 NHibernate 3 将枚举映射为 Int【英文标题】:Map Enum as Int with Fluent NHibernate and NHibernate 3 【发布时间】:2011-07-19 22:22:28 【问题描述】:

我过去使用此How do you map an enum as an int value with fluent NHibernate? 进行映射,但我最近升级到 NHibernate 3,这似乎不再起作用。我已经在我的 EnumConvention 类中放置了断点并且它们没有被击中。访问数据库的查询将枚举作为默认配置的字符串。

这如何与 NHibernate 3 一起工作?

更新

这是生成的映射文件的一部分:

<property name="ComponentType" type="FluentNHibernate.Mapping.GenericEnumMapper`1[[...ComponentType, ..., Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], FluentNHibernate, Version=1.1.0.0, Culture=neutral, PublicKeyToken=8aa435e3cb308880">
  <column name="ComponentTypeId" />
</property>

当为枚举指定IUserTypeConvention 时,使用GenericEnumMapper 似乎不正确。

这是我的约定:

public class EnumConvention : IUserTypeConvention

    public void Accept( IAcceptanceCriteria<IPropertyInspector> criteria )
    
        criteria.Expect( e => e.Property.PropertyType.IsEnum );
    

    public void Apply( IPropertyInstance instance )
    
        instance.CustomType( instance.Property.PropertyType );
    

【问题讨论】:

我真的不知道你能从这个练习中获得什么,但它可能已经被删除了,因为他们认为需要保留它 我没有看到它消失的任何地方,它似乎不再起作用了。那还能怎么做呢?做Map( ... ).CustomType&lt;int&gt;() 不起作用。它会导致问题。我会尝试做一个自定义的 IUserType,看看现在是否可行。 我说你有什么理由将它存储为 int 而不是 enum 啊。它实际上是作为一个表在数据库中,因此枚举的 int 与表行的 id 对齐。该表是固定的,不能更改,所以我想为它使用一个枚举。 【参考方案1】:

现在只需执行Map( m =&gt; m.MyEnum ).CustomType&lt;MyEnum&gt;() 似乎就可以了。

如果有人知道为什么IUserTypeConvention 在 NHibernate 3 中不能与 Fluent NHibernate 一起使用,我仍然想知道原因。也许是因为现在可以将自定义类型映射到枚举,但是为什么当时没有将其从 lib 中删除?

【讨论】:

简单的解决方案...为我节省了大量的调试时间! 这个解决方案对我来说比尝试定义一个约定更好。使用约定,未按预期在 SQL Server 2014 表上设置类型。【参考方案2】:

我在使用 Nhibernate 3.0GA 和 FluentNh(使用最新的 NH 版本重新构建)时遇到了类似的问题。 UserTypeConventions 未正确注册。

这里描述的问题: http://groups.google.com/group/nhusers/browse_thread/thread/c48da661f78bfad0

【讨论】:

【参考方案3】:

您不应该从 IUserTypeConvention 继承您的约定,而是从 FluentNHibernate.Conventions.UserTypeConvention 继承。

例如,这是我用来将布尔值和可为空的布尔值映射到名为 UserTrueFalseType 的自定义类型的确切约定:

    /// <summary>
/// Convention: Boolean fields map to CHAR(1) T/F/Null
/// </summary>
public class BooleanTrueFalseConvention : FluentNHibernate.Conventions.UserTypeConvention<UserTrueFalseType>

    /// <summary>
    /// Accept field type criteria
    /// </summary>
    /// <param name="criteria"></param>
    public override void Accept(FluentNHibernate.Conventions.AcceptanceCriteria.IAcceptanceCriteria<FluentNHibernate.Conventions.Inspections.IPropertyInspector> criteria)
    
        criteria.Expect(instance =>
            instance.Property.PropertyType.Equals(typeof(System.Boolean))
            ||
            instance.Property.PropertyType.Equals(typeof(System.Nullable<System.Boolean>))
        );
    

这适用于 NH 3.3 和 Fluent 的最新版本。

【讨论】:

以上是关于使用 Fluent NHibernate 和 NHibernate 3 将枚举映射为 Int的主要内容,如果未能解决你的问题,请参考以下文章

使用 Fluent NHibernate 和 NHibernate 3 将枚举映射为 Int

Fluent 映射和 NHibernate Xml 配置

如何使用 Fluent-NHibernate 和 MySQL 指定自动递增 (int) 标识列

如何使用 Fluent 设置 NHibernate.Burrow?

使用 Fluent NHibernate 和 AsList() 时指定主键

Fluent NHibernate使用我的用户名作为前缀创建表