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

时间:2010-11-05 21:50:35

标签: c# nhibernate events fluent-nhibernate identity

我们有一个新要求,即每个实体都必须具有用户可分配的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 之前它已保存到数据库但 ServerId由NHibernate填充?

P.S。我还假设Identity生成器不可能这样做,因为它保存到数据库然后获取数据库使用的ID。有人可以证实这一点吗?

1 个答案:

答案 0 :(得分:3)

感谢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;
    }
}