【问题标题】:Audit info in base class基类中的审计信息
【发布时间】:2012-03-28 19:49:14
【问题描述】:

我正在使用 NHIBERNATE 创建一个 ASP.NET MVC3 应用程序。我有一个基类 Entity,用于捕获一些审计信息,如 CreatedBy、CreatedOn、UpdatedBy、UpdatedOn 等。每当创建和持久化/更新派生类时,这些属性都应该自动填充。

由于 Entity 类型和所有其他类型都在 DOMAIN 程序集中定义,从Web 项目到 DOMAIN 以填充 Entity 基类中的信息

编辑

进一步,

  1. 目前,我将所有属性定义为 public virtual,那么如何实现它们以便在持久化时动态创建日期/userId。
  2. 我希望基类属性保留在派生具体类的每个表中(每个具体类的表)。如何使用 FLUENT NHIBERNATE 指定它(我没有使用自动映射)

【问题讨论】:

  • 各位天才,请帮忙。我相信这对于所有应用程序来说都是非常常见的场景。
  • Google 上有很多例子:“nhibernate 审计拦截器”。下面有比 Martin 更简单的例子。您还可以使用事件侦听器。需要注意的几件事:1)您必须更新实体的状态集合,因为这是持久化的。请参阅 Martin 示例中的“state[i]”; 2) 如果您已将 NHibernate 设置为使用动态 sql,则有一个错误会阻止它看到您的更改。见stackoverflow.com/questions/4383420/…

标签: c# asp.net asp.net-mvc visual-studio nhibernate


【解决方案1】:

打开会话时使用拦截器:

sessionFactory.OpenSession(new AuditInterceptor());

文件:AuditInterceptor.cs

using System;
using NHibernate;
using NHibernate.Type;
using System.Threading;
using System.Security;

namespace bla
{
    /// <summary>
    /// NHibernate Interceptor that stores audit information (idlogin and datetime.now) on every save and update
    /// </summary>
    public class AuditInterceptor : EmptyInterceptor
    {

        private int updates;
        private int creates;
        private int loads;
        private ISession session;

        public override void OnDelete(object entity,
                                      object id,
                                      object[] state,
                                      string[] propertyNames,
                                      IType[] types)
        {
            // do nothing
        }

        public override bool OnFlushDirty(object obj, object id, object[] currentState, object[] previousState, string[] propertyNames, IType[] types)
        {
            bool found = false;
            if (obj is Entity)
            {
                updates++;
                for (int i = 0; i < propertyNames.Length; i++)
                {
                    if ("dtlastchanged".Equals(propertyNames[i].ToLower()))
                    {
                        currentState[i] = DateTime.Now;
                        found = true;
                    }
                    if ("lastchangedby".Equals(propertyNames[i].ToLower()))
                    {
                        currentState[i] = this.session.Get<Login>(IdLogin, LockMode.None);
                        found = true;
                    }
                }
            }
            return found;
        }

        public override bool OnLoad(object obj, object id, object[] state, string[] propertyNames, IType[] types)
        {
            if (obj is Entity)
            {
                loads++;
            }
            return false;
        }

        public override bool OnSave(object entity,
                                    object id,
        object[] state,
        string[] propertyNames,
        IType[] types)
        {
            bool found = false;
            if (entity is Entity)
            {
                creates++;
                for (int i = 0; i < propertyNames.Length; i++)
                {
                    if ("dtlastchanged".Equals(propertyNames[i].ToLower()))
                    {
                        state[i] = DateTime.Now;
                        found = true;
                    }
                    if ("lastchangedby".Equals(propertyNames[i].ToLower()) && !(entity is Login && (entity as Login).IsInVerification))
                    {
                        state[i] = this.session.Get<Login>(IdLogin, LockMode.None);
                        found = true;
                    }
                }
            }
            return found;
        }

        public override void AfterTransactionCompletion(ITransaction tx)
        {
            //if (tx.WasCommitted)
            //{
            //    System.Console.WriteLine("Creations: " + creates + ", Updates: " + updates, "Loads: " + loads);
            //}
            updates = 0;
            creates = 0;
            loads = 0;
        }

        public override void SetSession(ISession session)
        {
            this.session = session;
            base.SetSession(session);
        }

        protected long IdLogin
        {
            get
            {
                return (Thread.CurrentPrincipal.Identity as CustomIdentity).IdLogin; // or something else that holds the id of the current logged in user
            }
        }
    }
}

【讨论】:

    猜你喜欢
    • 2011-02-05
    • 2016-02-28
    • 1970-01-01
    • 2020-11-06
    • 2015-09-08
    • 1970-01-01
    • 1970-01-01
    • 2015-01-23
    • 1970-01-01
    相关资源
    最近更新 更多