使用NServiceBus时的NHibernate ID生成器

使用NServiceBus时的NHibernate ID生成器,nhibernate,nservicebus,Nhibernate,Nservicebus,对于大多数CRUD应用程序,我使用NHibernate的guid.combID生成器。这样做的好处是,在刷新数据库之前,我可以访问ID,并且可以绕过与使用普通GUID相关的索引碎片问题 当我们引入消息传递时,会提出几个问题: 由于我们发送命令来更改域层,因此实际上我们无法访问UI中的“新”域对象。通常(对于web应用程序),我们需要它的标识符来重定向到另一个页面。一种解决方案是将id作为命令的一部分传递(例如Guid.NewGuid()),但是我们会丢失NHibernate提供的顺序Guid 如

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

当我们引入消息传递时,会提出几个问题:

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


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

    这是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);
        }
    

    也许你可以使用它:)

    这是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);
        }
    

    也许你可以使用它:)

    你能再解释一下工作流程吗?似乎您正在跟踪“会话”。通常,这是通过客户端生成的id完成的,与实体id无关。@AdamFyles这是web应用程序上相当常见的工作流。创建一个“创建”页面,将某些内容保存到数据库中,然后将您重定向到该项目的“编辑”页面。我只是对工作流程有所了解。我会在客户端生成一个id,并在您的实体id之外执行该操作。您能详细解释一下工作流吗?似乎您正在跟踪“会话”。通常,这是通过客户端生成的id完成的,与实体id无关。@AdamFyles这是web应用程序上相当常见的工作流。创建一个“创建”页面,将某些内容保存到数据库中,然后将您重定向到该项目的“编辑”页面。我只是对工作流程有所了解。我会在客户端生成一个id,并在您的实体id之外执行该id。