0
votes

Using NHibernate you can set an identity seed like so:

<column name="Column1" not-null="true" sql-type="int IDENTITY(1,1000)"/>

The FluentNHibernate IdentityPart has CustomType and SqlCustomType methods, neither does it for me though. Is there a way to fluently set an identity seed?

More info:

When I do this: Map(x => x.Id).Column("CustomerId").CustomSqlType("int IDENTITY(1,1000)"); I get this error: The entity 'Customer' doesn't have an Id mapped. Use the Id method to map your identity property. For example: Id(x => x.Id).

When I do this: Id(x => x.Id).Column("CustomerId").CustomSqlType("int IDENTITY(1,1000)"); I get this error: More than one column IDENTITY constraint specified for column 'CustomerId', table 'Customer'

Using FluentNHibernate 1.2.0.712.

2
You should avoid allowing the database generate keys for you, because it requires round-trips to retrieve the id's back to update the models and handle relationships while breaking batching. But even if you allow the DB to generate the keys, why would you want to change the seed?!? For development 1,1 is perfectly fine, in production you shouldn't be allowing NHibernate to generate/update the database. - Phill
@Phill Are you saying that because FluentNH does not have support for my scenario, then it's an invalid one? Thanks for the tip about the extra round-trips though. It's a non-issue in my case, but still, good to know. - Marcus

2 Answers

0
votes

I was able to duplicate that xml by doing something like this:

Map(x => x.LoginName, "Column1").CustomSqlType("int IDENTITY(1,1000)");

Edit:

If you can't achieve what you are wanting maybe you should explicitly map this using xml for now.

0
votes

There is the article at the link below about implementing custom identity generator (see: Part 1: Inheriting from TableGenerator class) but the example throws the exception for SQLite database ("SQLite errorr no such table: hibernate_unique_key"). Thus as regard SQLite there is no possibility to gain current id key from a table. It uses class TableGenerator from NHibernate API (NHibernate.Id);

http://nhforge.org/wikis/howtonh/creating-a-custom-id-generator-for-nhibernate.aspx

To avoid the exception I implemented another solution (especially the way of getting current Id). It takes advantage of Fluent-NHibernate API (GeneratedBy.Custom()). Look at the following source code:

public class MyAutoincrement<T> : IIdentifierGenerator where T : IId
{

    #region IIdentifierGenerator Members

    public object Generate(ISessionImplementor session, object obj)
    {
        NHibernate.ISession s = (NHibernate.ISession)session;

        int seedValue = 1000;
        int maxId = -1;//start autoincrement from zero! (fluent nhibernate start from 1 as default)

        List<T> recs = s.Query<T>().ToList<T>();

        if (recs.Count > 0)
        {
            maxId = recs.Max(x => x.getId());
        }

        return seedValue + maxId + 1;
    }

    #endregion
}

//Interface for access to current Id of table
public interface IId
{
    int getId();
}

//Entity
public class MyEntity : IId
{
    public virtual int Id { get; protected set; }
    public virtual string MyField1 { get; set; }
    public virtual string MyField2 { get; set; }

    #region IId Members

    public virtual int getId()
    {
        return this.Id;
    }

    #endregion
}

//Entity Mapping
public class MyEntityMap : ClassMap<MyEntity>
{
    public MyEntityMap()
    {
        Id(x => x.Id).GeneratedBy.Custom<MyAutoincrement<MyEntity>>();
        Map(x => x.MyField1);
        Map(x => x.MyField1);
    }
}

It works with SQLite database and involves custom identity seed.

Regards Bronek