使用 NServiceBus 时的 NHibernate ID 生成器

发布于 2024-12-08 16:47:15 字数 661 浏览 0 评论 0原文

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

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

  1. 由于我们发送命令来更改域层,因此我们实际上无法访问 UI 中的“新”域对象。通常(在 Web 应用程序的情况下)我们需要它的标识符来重定向到另一个页面。一种解决方案是将 id 作为命令的一部分传递(例如 Guid.NewGuid()),但这样我们就会丢失 NHibernate 提供的顺序 Guid。
  2. 如果我们使用身份策略,我们可以消除索引问题,但现在没有简单的方法可以从 UI 确定 id,除了订阅事件或同步执行命令,这两者在 Web 应用程序中都不是理想的选择。

所以我很好奇其他 NServiceBus 开发人员正在采取什么策略。对现有实体执行某些操作并不是真正的问题,因为我们只需使用ajax发送请求来分派命令,并通知用户一切都成功(可能)。由于他们所在的页面已经有更新的信息,这就足够了。

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

For most CRUD apps I use NHibernate's guid.comb ID generator. This has the advantage that I have access to the ID before I flush to the database and gets around the index fragmentation issue associated with using normal Guids.

When we introduce messaging it raises a few questions:

  1. Since we are sending commands to make changes to our domain layer, we don't actually have access to the "new" domain object in the UI. Often (in the case of a web application) we need it's identifier to redirect to another page. One solution would be to pass the id as part of the command (e.g. Guid.NewGuid()) but then we lose the sequential Guids that NHibernate provides.
  2. If we instead use an identity strategy we remove the index issue but now have no easy way of determining the id from the UI, other than subscribing to an event or executing he command synchronously, both of which are not ideal in a web application.

So I'm curious what strategy other NServiceBus developers are taking. Performing some operation on an existing entity is not really a problem since we can just send a request using ajax to dispatch the command, and notify the user that everything was successful (probably). Since the page they are on already has the updated information this is enough.

However when we create a new instance of a domain object (via a command) we often need to redirect the user to a page that then retrieves the newly created entity from our database. Of course this entity may not have been saved yet (as we are processing our commands async) and we typically need an Id to perform this redirect.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凉风有信 2024-12-15 16:47:15

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

也许你可以用它:)

This is the code that nhibernate uses to generate a comb.

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

Maybe you can use it :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文