NHibernate Hilo Sequence without NHibernate
I have one application which uses NHibernate to save entities to a database, and it uses the HiLo generate of NHibernate to create the id's. I have another application which I need to save data to the same table, however in this application, I'm not using NHibernate. Is there a simple way to use HiLo without adding reference to NHibernate and mapping files?
<id name="EntityId" unsaved-value="0" >
<column name="EntityId" sql-type="int" not-null="true" />
<generator class="hilo">
<param name="table">hibernate_unique_key</param>
<param name="column">next_hi</param>
<param name="max_lo">1000</param>
</generator>
</id>
Update: I created a new method to get the next id which I believe has the same behavior as the NHibernate HiLo sequence. I'm not putting any locks on the database, so if this were a high frequency table that I was inserting to, it could be an issue, but for very low frequency, there is a very low possibility that there may be a concurrency issue.
/// <summary>
/// Gets the next entity id.
/// </summary>
/// <returns></returns>
public static int GetNextAvailableEntityId()
{
int max_lo = 1000;
int nextHi = DefaultContext.Database.SqlQuery<int>("select next_hi from hibernate_unique_key").Single();
int nextRangeStart = max_lo * nextHi;
int currentMax = DefaultContext.Database.SqlQuery<int>("SELECT MAX(entityid) FROM Entities").Single();
if (currentMax < nextR开发者_如何学GoangeStart)
{
return currentMax + 1;
}
else
{
DefaultContext.Database.ExecuteSqlCommand("update hibernate_unique_key set next_hi = next_hi + 1");
return nextHi;
}
}
If in doubt, take a look at NH's code to be sure that you implement it correctly.
It is something like this:
- open a separate transaction, increment and read the next high value, commit
- create 1000 ids by next_high * 1000 + x
- when you run out of ids, start again
You can create a single instance of an id generator for all transaction of the same process. Make sure that your id generator is thread safe.
精彩评论