【问题标题】:NHibernate - How to get linked entity value in postinsert event for audit logging purposeNHibernate - 如何在 postinsert 事件中获取链接实体值以用于审计日志记录
【发布时间】:2013-12-28 22:05:25
【问题描述】:

在使用事件侦听器实现审计日志记录时,如何在 nhibernate 中获取链接实体(外键)值。 我能够记录除链接实体之外的所有实体属性,它只记录链接实体的名称而不是值。

如果有人能指出我正确的方向或提供示例代码,那就太好了。 这是我目前所拥有的。

public void OnPostInsert(PostInsertEvent @event)
{
        if (@event.Entity is AuditLog)
        {
            return;
        }

        ISession session = @event.Session.GetSession(EntityMode.Poco);
        string username = httpContextHelper.GetCurrentUsersLoginName();
        var props = @event.State;

        for (int i = 0; i < props.Length; i++)
        {
            string newValue = string.Empty;

            //Tried this but obj always null............

            //var obj = props[i] as INHibernateProxy;
            //if (obj != null)
            //{
            //   newValue = obj.HibernateLazyInitializer.Identifier.ToString();
            //   session.Evict(props[i]);
            //}

            newValue = (props[i] == null) ? string.Empty : props[i].ToString();

            if (props[i] != null)
            {
                session.Save(new AuditLog
                {
                    AuditEntryType = "Insert",
                    DomainFullName = @event.Entity.GetType().FullName,
                    DomainShortName = @event.Entity.GetType().Name,
                    OldValue = string.Empty,
                    FieldName = @event.Persister.PropertyNames[i],
                    NewValue = newValue,
                    DomainId = (int)@event.Id,
                    Timestamp = DateTime.Now,
                    Username = username
                });
            }
        }
    }

【问题讨论】:

    标签: nhibernate logging event-listener audit


    【解决方案1】:

    您的链接对象属性是引用链接对象本身还是 ID 值?

    如果您的属性是链接对象,您的方法将简单地调用链接对象上的 .ToString() 方法,默认情况下是类名。如果您在下面的示例中记录博客,作者将只是类名,如“MyNamespace.Author”,或者您在覆盖 .ToString() 时输出的任何内容。

    public class Blog
    {
        public virtual int ID {get;set;} 
    
        public virtual string Name {get;set;}
    
        public virtual Author Author {get;set;}
    
        // more properties
    }
    
    public class Author
    {
        public virtual int ID {get;set;} 
    
        public virtual string Name {get;set;}
    
        public virtual DateTime Birthday {get;set;}
    }
    
    // property design as used with XML mappings
    

    您有多种选择:

    • 添加另一个带有 Foreign ID 的属性,例如“int AuthorID”,并将其映射到 FK 列
    • 使用 .ToString() 实现,它允许您识别相关对象(仅人类可读)。
    • 获取对象的 ID,例如“blogToLog.Author.ID”。这有一些缺点:您需要在日志记录例程中使用特殊情况,如果尚未加载,日志记录可能会调用相关对象的延迟加载(意思是:从数据库加载仅用于日志记录)。
    • 创建一个带有 ID 属性的接口,让你所有的持久类实现它,如果你的属性是类类型,则转换成它并输出 ID。

    【讨论】:

      【解决方案2】:

      为什么不在@event.Entity 中按名称获取属性值。我不确定名称在 hibernate 中的位置,因为在 nhibernate (c#) 中检查我的 src 是一个名为 propertyNames 的参数,我可以使用反射来获取它们。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-06-26
        • 2010-10-09
        • 1970-01-01
        • 1970-01-01
        • 2011-02-02
        • 2023-01-23
        • 1970-01-01
        • 2012-08-10
        相关资源
        最近更新 更多