Compound primary keys and NHibernate event listeners November 7, 2019

Recently I had to write some code to log CUD operations done via NHibernate. The requirement was to log the following:

It was pretty straightforward apart from retrieving the primary key. If the key is a scalar then it’s pretty straightforward:

public void OnPostInsert(PostInsertEvent @event)
{
    string entityName = @event.Entity.GetType().Name;
    string entityIdPropertyName = @event.Persister.IdentifierPropertyName ?? "ID";
    string entityIdValue = @event.Id.ToString();
}

Unfortunately it’s not at all straightforward how you’re supposed to do this when the entity/table uses a compound primary key. I eventually came up with the following:

if (@event.Persister.IdentifierType is NHibernate.Type.EmbeddedComponentType identifierType)
{
    // This entity has a composite primary key.

    foreach (var propertyName in identifierType.PropertyNames)
    {
        // Because we only have the name of the property we have to use reflection to get
        // the corresponding value.
        object propertyValue = @event.Id.GetType().GetProperty(propertyName).GetValue(entityId);
    }
}