adaam
adaam

Reputation: 3706

Automatically generate Created date in Fluent NHibernate Automapping

I am using Fluent NHibernate's automapping / conventions functionality to map my entities to database tables. I have this abstract class which every domain entity in my application derives itself from:

public abstract class Entity
{
    public virtual int Id { get; protected internal set; }
    public virtual DateTime Created { get; set; }
}

How can I modify my Fluent configuration so that the Created property has it's value automatically set to the value of DateTime.Now when the record is saved in the database.

Here is my Fluent configuration for reference:

private FluentNHibernate.Cfg.FluentConfiguration GetConfiguration()
{

    return Fluently
        .Configure()
        .Database(() =>
            {
                return MsSqlConfiguration.MsSql2012.ConnectionString(x => x.FromConnectionStringWithKey("main"));
            }                                     
        )
        .Mappings(
            x =>
            {
                var persistenceModel = new PersistenceModel() { ValidationEnabled = false };
                x.UsePersistenceModel(persistenceModel)
                 .AutoMappings.Add(
                    AutoMap.AssemblyOf<Entity>().Where(Exceptions.Load)
                    .Conventions.Add(FluentNHibernate.Conventions.Helpers.DefaultLazy.Never())
                    .Conventions.Add(FluentNHibernate.Conventions.Helpers.DefaultCascade.SaveUpdate())
                    .Conventions.Add(new FluentNHibernate.Conventions.Helpers.Builders.JoinConventionBuilder().Always(a => a.Fetch.Join()))
                );
            }
        )
        .ExposeConfiguration(BuildSchema);
}

Upvotes: 0

Views: 807

Answers (1)

Mert
Mert

Reputation: 6572

you should use NHibernate’s event listeners for this;

public class AuditEventListener : IPreUpdateEventListener, IPreInsertEventListener
{
    public bool OnPreUpdate(PreUpdateEvent @event)
    {
        var audit = @event.Entity as IHaveAuditInformation;
        if (audit == null)
            return false;

        var time = DateTime.Now;
        var name = WindowsIdentity.GetCurrent().Name;

        Set(@event.Persister, @event.State, "UpdatedAt", time);
        Set(@event.Persister, @event.State, "UpdatedBy", name);

        audit.UpdatedAt = time;
        audit.UpdatedBy = name;

        return false;
    }

    public bool OnPreInsert(PreInsertEvent @event)
    {
        var audit = @event.Entity as IHaveAuditInformation;
        if (audit == null)
            return false;


        var time = DateTime.Now;
        var name = WindowsIdentity.GetCurrent().Name;

        Set(@event.Persister, @event.State, "CreatedAt", time);
        Set(@event.Persister, @event.State, "UpdatedAt", time);
        Set(@event.Persister, @event.State, "CreatedBy", name);
        Set(@event.Persister, @event.State, "UpdatedBy", name);

        audit.CreatedAt = time;
        audit.CreatedBy = name;
        audit.UpdatedAt = time;
        audit.UpdatedBy = name;

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

https://ayende.com/blog/3987/nhibernate-ipreupdateeventlistener-ipreinserteventlistener

Upvotes: 2

Related Questions