代码之家  ›  专栏  ›  技术社区  ›  Matt Florence

Fluent NHibernate自动递增非键(ID)属性

  •  13
  • Matt Florence  · 技术社区  · 15 年前

    是否可以由数据库管理类自动增量的整数属性,但不能是主键(或NHibernate引用的ID)?我很难找到这样做的例子。任何帮助都将不胜感激。谢谢。

    2 回复  |  直到 13 年前
        1
  •  9
  •   anonymous    15 年前

    两种选择。

    • 如果数据库对此负有100%的责任,您只需告诉nhibernate该属性是生成的,而不需要将其包含在任何更新/isnerts中。缺点是NH需要做一个额外的选择来保持值在内存中的新鲜度。

      <property name=“foo”generated=“always”update=“false”insert=“false”/>

    • 如果数据库不负责,并且您只希望自动完成这项工作,那么可以使用拦截器在插入时将值设置为1,在更新时将值增加1。

    http://www.nhforge.org/doc/nh/en/index.html#objectstate-interceptors (11.1-拦截器)

    您将重写onSave()以查找属性并设置初始值,然后重写onFlushDirty()以查找属性和增量。


    编辑:

    我是个白痴,没注意到你说的很流利。


    编辑第2页:

    我认为您可能还对将此列用作版本控制感兴趣?

    < version name="Foo" generated="always" />
    
        2
  •  5
  •   Fernando Neira    13 年前

    这对我很有用:

    public class Potato
    {
        public virtual Guid Id { get; protected set; }
        public virtual int LegacyId { get; protected set; }
    }
    
    public class PotatoMap : ClassMap<Potato>
    {
        public PotatoMap()
        {
            Id(x => x.Id).GeneratedBy.GuidComb();
            Map(x => x.LegacyId).CustomSqlType("INT IDENTITY(1,1)").Not.Nullable().ReadOnly().Generated.Insert();
        }
    }
    

    基本上,整数被设置为由数据库生成,nhibernate被指示在插入时检索它。

    重要的是要注意,映射只是答案的一半,它将 如果列不是作为标识创建的,则工作。 CuffSql类型 添加到映射中,目的是在使用SchemaExport生成表时创建正确的SQL。这是生成的SQL:

     create table [Potato] (
             Id UNIQUEIDENTIFIER not null,
            LegacyId INT IDENTITY(1,1) not null,
            primary key (Id)
         )
    

    另一方面,readonly和generated.insert()将告诉nhibernate,该值仅在插入时由数据库自动生成,因此它必须在每次插入时查询数据库中的值。

    注意,我只在SQL Server中测试了这个。自定义类型可能会更改,或者在其他数据库中不可用。