代码之家  ›  专栏  ›  技术社区  ›  Ian Nelson

枚举到整数的映射导致每次刷新时更新

  •  22
  • Ian Nelson  · 技术社区  · 14 年前

    我正在尝试将模型中的枚举属性(System.DayOfWeek实例)映射到整数数据库字段。 模型中的其他枚举属性应映射到字符串,因此我不希望定义约定。

    我理解使用流畅的映射可以做到这一点,比如:

    map(x=>x.dayOfWeek).customType<int>();
    < /代码> 
    
    

    事实上,乍一看,这似乎是可行的。

    但是,我注意到,每次刷新会话时,都会更新以这种方式映射属性的实体实例,即使没有对它们进行任何修改。

    为了找出导致这种刷新的原因,我设置了一个ipreupdateEventListener,并检查了实体的旧状态和状态。 见附图。在oldstate中,相关对象是int,而在state中则是dayofweek。

    如果使用未指定类型属性的HBM XML映射,则不会出现此问题。

    所以…

    这是一个bug还是genericEnummapper的缺点? 是否有任何方法告诉FNH映射不要在生成的HBM上指定任何类型属性? 如果不是,我可以指定NH用于枚举的默认类型吗(这是什么)?

    =

    我理解,使用流畅的映射可以做到这一点,比如:

    Map(x => x.DayOfWeek).CustomType<int>();
    

    事实上,乍一看,这似乎是有效的。

    但是,我注意到,每次刷新会话时,都会更新以这种方式映射属性的实体实例,即使没有对其进行任何修改。

    为了找出导致这种刷新的原因,我设置了一个ipreupdateEventListener,并检查了实体的旧状态和状态。 见附图。在oldstate中,相关对象是int,而在state中则是dayofweek。

    如果使用未指定类型属性的HBM XML映射,则不会出现此问题。

    所以…

    这是一个bug还是genericEnummapper的缺点? 是否有任何方法告诉FNH映射不要在生成的HBM上指定任何类型属性? 如果不是,我可以指定NH用于枚举的默认类型吗(这是什么)?

    6 回复  |  直到 11 年前
        1
  •  23
  •   mhenrixon    14 年前

    如果使用我的枚举约定,就不会有问题。

    public class EnumConvention : IPropertyConvention, IPropertyConventionAcceptance
    {
        public void Apply(IPropertyInstance instance)
        {
            instance.CustomType(instance.Property.PropertyType);
        }
    
        public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
        {
            criteria.Expect(x => x.Property.PropertyType == typeof(AddressType)  ||
                x.Property.PropertyType == typeof(Status) ||
                x.Property.PropertyType == typeof(DayOfWeek));
        }
    }
    

    然后您可以像常规那样映射您的属性:

    Map(x => x.DayOfWeek);
    

    编辑: 已更新约定以选取要用于int转换的特定枚举。此处未选中的所有枚举都将映射为字符串。你可能需要对实际测试的对象做一点实验。我不确定PropertyType是否直接执行此操作。

        2
  •  5
  •   Luiz Angelo    11 年前

    我知道我参加晚会迟到了——这个问题已经过去两年了。但是,既然我偶然发现了这一点,我可能会为自己补充解决问题的方法:

    Map(x => x.DayOfWeek).CustomType<enumType>();
    

    它给了我一个窍门:每次都停止更新。

    来源: https://groups.google.com/forum/#!searchin/fluent-nhibernate/enum/fluent-nhibernate/bBXlDRvphDw/AFnYs9ei7O0J

        3
  •  4
  •   Goblin    14 年前

    我使用的一个解决方法是使用一个int支持字段,并让nhibernate使用它进行映射。

    每当NHibernate必须执行强制转换以将新值与旧值进行比较时(它总是标记为脏值),就会导致刷新。

        4
  •  1
  •   Constantin    14 年前

    对我来说,最简单的方法是将映射的自定义类型从 int PersistentEnumType . 确保声明一个通用版本以使您的生活更轻松:

    public class PersistentEnumType<T> : PersistentEnumType {
        public PersistentEnumType() : base(typeof(T)) {}
    }
    

    然后使用

    Map(x => x.DayOfWeek)
        .CustomType<PersistentEnumType<System.DayOfWeek>>();
    

    这不需要更改实体,只需要映射,并且可以基于每个属性应用。

    查看更多 here .

        5
  •  0
  •   DavidWhitney    14 年前

    这取决于您是否需要将DayOfWeek特别设置为整数。

    如果将强制转换作为映射的一部分,则相等将始终失败,并且属性将被标记为脏属性。

    我可能会画:

    map(x=>x.dayOfWeek).customType();

    并创建一个只读属性,如果确实需要,它将dayOfWeek值显示为整数。无论如何,作为实际类型的映射应该可以工作并防止错误的脏。

        6
  •  0
  •   DanP    14 年前

    你可以考虑另一种方法;我发现了法比奥·莫洛的用法 well known instance types 对于这种用途是无价的。每当您试图扩展基本枚举的功能(例如提供本地化的描述等)时,这些功能的好处就会立即显现出来。