使用NServiceBus时的NHibernate ID生成器

时间:2011-10-07 14:07:19

标签: nhibernate nservicebus

对于大多数CRUD应用程序,我使用NHibernate的guid.comb ID生成器。这样做的好处是我可以在刷新数据库之前访问ID,并解决与使用普通Guid相关的索引碎片问题。

当我们介绍消息时,它提出了一些问题:

  1. 由于我们发送命令对域层进行更改,因此我们实际上无法访问UI中的“新”域对象。通常(在Web应用程序的情况下)我们需要将其标识符重定向到另一个页面。一种解决方案是将id作为命令的一部分传递(例如Guid.NewGuid())但是我们丢失了NHibernate提供的顺序Guids。
  2. 如果我们改为使用身份策略,我们会删除索引问题但现在没有简单的方法来确定UI中的id,除了订阅事件或同步执行命令之外,这两者在Web中都不理想应用
  3. 所以我很好奇其他NServiceBus开发人员正在采取什么策略。在现有实体上执行某些操作并不是真正的问题,因为我们可以使用ajax发送请求来分派命令,并通知用户一切都成功(可能)。由于他们所在的页面已经有了更新的信息,这就足够了。

    但是,当我们创建域对象的新实例(通过命令)时,我们经常需要将用户重定向到一个页面,然后从我们的数据库中检索新创建的实体。当然这个实体可能尚未保存(因为我们正在处理我们的命令异步),我们通常需要一个Id来执行此重定向。

1 个答案:

答案 0 :(得分:1)

这是nhibernate用来生成梳子的代码。

private Guid Generate()
    {
        byte[] guidArray = Guid.NewGuid().ToByteArray();

        DateTime baseDate = new DateTime(1900, 1, 1);
        DateTime now = DateTime.Now;

        // Get the days and milliseconds which will be used to build the byte string 
        TimeSpan days = new TimeSpan(now.Ticks - baseDate.Ticks);
        TimeSpan msecs = now.TimeOfDay;

        // Convert to a byte array 
        // SQL Server is accurate to 1/300th of a millisecond so we divide by 3.333333 
        byte[] daysArray = BitConverter.GetBytes(days.Days);
        byte[] msecsArray = BitConverter.GetBytes((long)(msecs.TotalMilliseconds / 3.333333));

        // Reverse the bytes to match SQL Servers ordering 
        Array.Reverse(daysArray);
        Array.Reverse(msecsArray);

        // Copy the bytes into the guid 
        Array.Copy(daysArray, daysArray.Length - 2, guidArray, guidArray.Length - 6, 2);
        Array.Copy(msecsArray, msecsArray.Length - 4, guidArray, guidArray.Length - 4, 4);

        return new Guid(guidArray);
    }

也许你可以使用它:)