我可以使用nhibernate来判断属性是否脏了吗?

时间:2009-02-12 15:42:32

标签: nhibernate

是否有人知道是否可以使用NHibernate判断对象上的特定属性是否脏(即属性与存储在数据库中的属性不同)?

这个问题的背景是我将拥有一个具有(相对)大量属性的对象。我需要能够将一个参数(字符串)传递给一个函数,该函数将确定该特定属性是否在页面的生命周期内发生了变化。

如果我需要,我可以创建对象的副本,并在页面生命周期结束时使用反射来检查值,但我不愿意这样做。如果NHibernate可以简单地告诉我房产是否脏,那将是很好的。

由于

2 个答案:

答案 0 :(得分:1)

目前还没有通过nHibernate(或Hibnernate,AFAIK)API提供。您可以通过在加载到会话中时存储对象的状态来自己编写类似的东西,然后比较它们。

注意:我自己没有看过这个,但是,如果你没有锁定ORM选择,你应该看看Subsonic。在对象本身内跟踪了很多脏状态,您可以确定特定属性是否脏。

答案 1 :(得分:0)

通过手动检查 IPersistenceContext 可以检查 property 是否脏。我从未尝试过,所以我无法提供确切的代码。您可以参考以下代码示例中的 GetEntityEntryFromPersistenceContext 方法并编写自己的代码来执行此操作。

您可以轻松检查整个实体是否脏了。您可以使用以下实用程序类来了解实体的各种状态,包括脏状态。

public static class NHibernateUtil
{
    public static bool IsDirtyEntity<TEntity>(ISession session, TEntity instance) where TEntity : class
    {
        if(IsPersistentEntity(session, instance, true) == false)
        {
            throw new NhBoilerplateException("This is not a persistent entity.");
        }

        ISessionImplementor sessionImpl = session.GetSessionImplementation();
        IPersistenceContext persistenceContext = sessionImpl.PersistenceContext;
        EntityEntry oldEntry = sessionImpl.PersistenceContext.GetEntry(instance);

        if((oldEntry == null) && (instance is INHibernateProxy))
        {
            INHibernateProxy proxy = instance as INHibernateProxy;
            object obj = sessionImpl.PersistenceContext.Unproxy(proxy);
            oldEntry = sessionImpl.PersistenceContext.GetEntry(obj);
        }

        string className = NHibernateProxyHelper.GuessClass(instance).FullName;
        IEntityPersister persister = sessionImpl.Factory.GetEntityPersister(className);
        object[] oldState = oldEntry.LoadedState;
        object[] currentState = persister.GetPropertyValues(instance);
        int[] dirtyProps = persister.FindDirty(currentState, oldState, instance, sessionImpl);

        return (dirtyProps != null);
    }

    public static bool IsProxyEntity<TEntity>(TEntity instance) where TEntity : class
    {
        if((instance is INHibernateProxy) == false)
            return false;
        else
            return true;
    }

    public static bool IsPersistentEntity<TEntity>(ISession session, TEntity instance, bool validateProxy) where TEntity : class
    {
        EntityEntry oldEntry = GetEntityEntryFromPersistenceContext(session, instance);

        if(oldEntry != null)
            return true;

        if(validateProxy == false)
            return false;

        if(IsProxyEntity(instance) == true)
            return true;
        else
            return false;
    }

    public static EntityEntry GetEntityEntryFromPersistenceContext<TEntity>(ISession session, TEntity instance) where TEntity : class
    {
        ISessionImplementor sessionImpl = session.GetSessionImplementation();
        IPersistenceContext persistenceContext = sessionImpl.PersistenceContext;
        EntityEntry oldEntry = persistenceContext.GetEntry(instance);
        return oldEntry;
    }
}