2011-09-02 36 views
4

我有一个应用程序使用NHibernate将实体保存到数据库,并且它使用HiLo生成NHibernate来创建id。我有另一个应用程序,我需要将数据保存到同一张表,但是在这个应用程序中,我没有使用NHibernate。有没有简单的方法来使用HiLo而无需添加对NHibernate和映射文件的引用?NHibernate Hilo序列没有NHibernate

<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> 

更新:我创建了一个新的方法来获得下一个id,我相信它具有与NHibernate HiLo序列相同的行为。我没有对数据库进行任何锁定,因此如果这是我插入的高频表,这可能是一个问题,但对于频率很低的情况,可能存在并发问题的可能性很低。

/// <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 < nextRangeStart) 
    { 
     return currentMax + 1; 
    } 
    else 
    { 
     DefaultContext.Database.ExecuteSqlCommand("update hibernate_unique_key set next_hi = next_hi + 1"); 
     return nextHi; 
    } 
} 
+0

我建议将您的NH配置发布给您的HiLo列,以便给出精确的答案,而不是泛化。换句话说,你的参数值是什么? http://stackoverflow.com/questions/2738671/please-explain-nhibernate-hilo/7084697#7084697 – Brook

+0

我更新了帖子,包括HiLo配置... – mservidio

+0

只是为了确认,你使用的是同样的密钥表, hibernate_unique_key'所有的实体? – Brook

回答

3

如果有疑问,请看看NH的代码,以确保您正确实施它。

它是这样的:

  • 打开一个单独的事务,增量和读取下一个高价值,提交
  • 通过创建1000个IDS next_high * 1000 + X
  • 当您运行的
  • ids,再次启动

您可以为同一进程的所有事务创建一个id生成器的单个实例。确保你的id生成器是线程安全的。

+0

谢谢。我现在看看这个:http://nhibernate.svn.sourceforge.net/viewvc/nhibernate/tags/3.2.0GA/nhibernate/src/NHibernate/Id/SequenceHiLoGenerator.cs?revision=6038&view=markup – mservidio

+0

具有单独交易的部分不明显。我希望我的回答有帮助。 –

+0

我上面的实现可能会略有不同。因此,当max_lo设置为1000时,NHibernate实际上会保留1000个ID。在事务关闭后,任何后续事务都有下一个可用事务处理1000个事务? – mservidio