在将实体保存到数据库之前,如何在 NHibernate 侦听器中获取实体的 ID?

发布于 2024-09-30 12:41:35 字数 916 浏览 6 评论 0原文

我们有一个新要求,即每个实体都必须有一个用户可分配的 ID:

public class Entity
{
    public int ServerId { get; set; }
    public int UserId { get; set; }
}

ServerId 是使用 HiLo 自动生成的 ID,UserId 是用户指定的 ID。但是,如果用户未设置 UserId,则应默认为 ServerId。所以我创建了一个像这样的监听器:

public class CustomEventListener : IPreInsertEventListener
{
    public bool OnPreInsert(PreInsertEvent @event)
    {
        var entity = @event.Entity as Entity;

        if (entity.UserId == 0)
        {
            entity.UserId = entity.ServerId;
        }

        return false;
    }
}

不幸的是,在这个预插入阶段,ServerId始终为0,因此UserId始终为0。有谁知道我该怎么做获取生成的ServerId 保存到数据库之前但之后由NHibernate填充ServerId

PS 我还假设这对于 Identity 生成器来说是不可能的,因为它保存到数据库,然后获取数据库使用的 ID。有人可以证实这一点吗?

We have a new requirement that every entity must have a user-assignable ID:

public class Entity
{
    public int ServerId { get; set; }
    public int UserId { get; set; }
}

The ServerId is an auto-generated ID using HiLo and the UserId is the user-specified ID. However, if the user does NOT set a UserId, it should default to whatever ServerId is. So I created a listener like this:

public class CustomEventListener : IPreInsertEventListener
{
    public bool OnPreInsert(PreInsertEvent @event)
    {
        var entity = @event.Entity as Entity;

        if (entity.UserId == 0)
        {
            entity.UserId = entity.ServerId;
        }

        return false;
    }
}

Unfortunately, at this pre-insert stage, the ServerId is always 0, so the UserId is always 0. Does anyone know how I can get the generated ServerId before it's saved to the database but after the ServerId is populated by NHibernate?

P.S. I'm also assuming that this is impossible with the Identity generator because it saves to the database and then gets the ID that the DB used. Can someone confirm this?

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

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

发布评论

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

评论(1

也只是曾经 2024-10-07 12:41:35

感谢 Ayende 的博客文章在这里找到了解决方案:

http ://ayende.com/Blog/archive/2009/04/29/nhibernate-ipreupdateeventlistener-amp-ipreinserteventlistener.aspx

结果你不仅要在实体中更改它,还要更改实体状态:

public class CustomEventListener : IPreInsertEventListener
{
    public bool OnPreInsert(PreInsertEvent @event)
    {
        var entity = @event.Entity as Entity;

        if (entity.UserId == 0)
        {
            entity.UserId = entity.ServerId;
            Set(@event.Persister, @event.State, "UserId", entity.UserId);
        }

        return false;
    }

    private void Set(IEntityPersister persister, object[] state, string propertyName, object value)
    {
        var index = Array.IndexOf(persister.PropertyNames, propertyName);
        if (index == -1)
            return;
        state[index] = value;
    }
}

Found the solution thanks to Ayende's blog post here:

http://ayende.com/Blog/archive/2009/04/29/nhibernate-ipreupdateeventlistener-amp-ipreinserteventlistener.aspx

Turns out you have to not only change it in the entity, but also the entity state:

public class CustomEventListener : IPreInsertEventListener
{
    public bool OnPreInsert(PreInsertEvent @event)
    {
        var entity = @event.Entity as Entity;

        if (entity.UserId == 0)
        {
            entity.UserId = entity.ServerId;
            Set(@event.Persister, @event.State, "UserId", entity.UserId);
        }

        return false;
    }

    private void Set(IEntityPersister persister, object[] state, string propertyName, object value)
    {
        var index = Array.IndexOf(persister.PropertyNames, propertyName);
        if (index == -1)
            return;
        state[index] = value;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文