检查实体(属性和集合)是否脏

时间:2011-06-30 05:34:17

标签: c# .net nhibernate

我有一个具有许多一对一关系的实体(cascade =“all-delete-orphan”)和集合。

我想检查一下这个实体是不是很脏(包括它与那些一对一关系的集合和属性/实体),有什么方法可以做到吗?

我关注this文章,但它没有涵盖我需要的所有内容,我们将不胜感激任何帮助。

2 个答案:

答案 0 :(得分:1)

onFlushDirty(...)方法(在Hibernate中扩展EmptyInterceptor)可以帮我检查脏集合。具有嵌套集合的父实体被传递到onFlushDirty,但我不知道传入的实体可能是集合元素。一旦我发现它,它既适用于嵌套集合又适用于其父实体。

public class PropertyChangeInterceptor extends EmptyInterceptor{

public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types)

另一种方法onCollectionUpdate(...)也可用于捕获脏集合,它在onFlushDirty(...)之后调用。

答案 1 :(得分:0)

您可以使用NHibernate监听器,如下所示:

public class AuditUpdateListener : IPostUpdateEventListener
{
    private const string _noValueString = "*No Value*";

    private static string getStringValueFromStateArray(object[] stateArray, int position)
    {
        var value = stateArray[position];

        return value == null || value.ToString() == string.Empty
                ? _noValueString
                : value.ToString();
    }

    public void OnPostUpdate(PostUpdateEvent @event)
    {
        if (@event.Entity is AuditLogEntry)
        {
            return;
        }

        var entityFullName = @event.Entity.GetType().FullName;

        if (@event.OldState == null)
        {
            throw new ArgumentNullException("No old state available for entity type '" + entityFullName +
                                            "'. Make sure you're loading it into Session before modifying and saving it.");
        }

        int[] dirtyFieldIndexes = @event.Persister.FindDirty(@event.State, @event.OldState, @event.Entity, @event.Session);

        ISession session = @event.Session.GetSession(EntityMode.Poco);

        string entityName = @event.Entity.GetType().Name;
        string entityId = @event.Id.ToString();

        foreach (int dirtyFieldIndex in dirtyFieldIndexes)
        {
            //For component types, check:
            //  @event.Persister.PropertyTypes[dirtyFieldIndex] is ComponentType

            var oldValue = getStringValueFromStateArray(@event.OldState, dirtyFieldIndex);
            var newValue = getStringValueFromStateArray(@event.State, dirtyFieldIndex);

            if (oldValue == newValue)
            {
                continue;
            }

            // Log
            session.Save(new AuditLogEntry
                                {
                                    EntityShortName = entityName,
                                    FieldName = @event.Persister.PropertyNames[dirtyFieldIndex],
                                    EntityFullName = entityFullName,
                                    OldValue = oldValue,
                                    NewValue = newValue,
                                    Username = Environment.UserName,
                                    EntityId = entityId,
                                    AuditEntryType = AuditEntryType.PostUpdate
                                });
        }

        session.Flush();
    }
}