NHibernate逐出ID [英] NHibernate evict by id

查看:85
本文介绍了NHibernate逐出ID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

每个人都知道会话中有缓存. 通常可以通过以下两种方法清除此缓存:

Everyone knows that there is cache in session. This cache generally could be cleared by 2 methods:

  1. Session.Evict
  2. Session.Clear

第二种方法不仅删除了单个条目,还删除了所有缓存.

Second method removes all cache not only for single entry.

我有经营方法.它接收大对象的ID(来自aspx站点),有时还接收多个ID.并在数据库中执行本机sql操作(使用具有复杂逻辑的sql-query来不加载C#中的所有数据).然后,我需要使缓存无效.因此,每个潜在的对象负载都无需数据库直接缓存.

I have business method. It receives id of large object (from aspx site) or sometimes several ids. And do native sql operation in database (using sql-query with complex logic to not load all data in C#). Then I need to invalidate cache. So every potential load of object goes without cache direct from database.

不幸的是,退出了仅接受对象.同样,其实现DefaultEvictEventListener在代码路径中也有明确的分隔符-对于代理类而不是代理类而言,是分开的.我只是尝试创建实体,手动填写id并将其传递给Evict.这是行不通的.据我了解,通过非代理类的Evict使用GetHashCode可以从缓存中查找和删除对象.因此,如果我不重写它,将无法正常工作.我有很多本机sql批处理操作,因此在所有实体对象中覆盖所有GetHashcode会产生很多工作.另外我不确定这种情况是从缓存中删除代理还是不删除代理. 更新:据我所知,覆盖GetHashCode也无济于事.找不到StatefulPersistenceContext.RemoveEntry实体,因为它使用RuntimeHelpers.GetHashCode.因此,这种解决方案甚至是不可能的

Unfortunately evict accepting only objects. Also its implementation DefaultEvictEventListener has clear separation in code path - separate for proxy and not proxied classes. I have tried simply to create entity, fill id manually and pass it to Evict. This will not works. As I understand Evict by not proxied class use GetHashCode to find and remove object from cache. So if I am not overriding it it will not works. I have a lot native sql batch operations so overriding all GetHashcode in all entities objects will create a lot of work. Also I am not sure is this case removes proxies from cache or no. Update: As far as I have tried for me overriding GetHashCode also not helped. StatefulPersistenceContext.RemoveEntry not found entity because it uses RuntimeHelpers.GetHashCode. So this solution is not even possible

使用NHibernate的来源,我产生了以下解决方案:

Using sources of NHibernate I have produced following solution:

public static class NHSessionHelper: DefaultEvictEventListener
 public static void RemoveEntityFromCache(this ISession session, Type type, object entityId)
    {
        ISessionImplementor sessionImpl = session.GetSessionImplementation();
        IPersistenceContext persistenceContext = sessionImpl.PersistenceContext;
        IEntityPersister persister = sessionImpl.Factory.GetEntityPersister(type.FullName);

        if (persister == null)
        {
            return;
        }

        EntityKey key = new EntityKey(entityId, persister, sessionImpl.EntityMode);
        persistenceContext.RemoveProxy(key);

        object entity = persistenceContext.RemoveEntity(key);
        if (entity != null)
        {
            EntityEntry e = persistenceContext.RemoveEntry(entity);
            DoEvict(entity, key, e.Persister, (IEventSource)sessionImpl);
        }
    }

它仅使用NHibenate实现的一部分.但是在我看来,复制代码不是一个好主意.可能还有其他想法吗?

It just uses part of NHibenate implementation. But it seem to me not good idea to duplicate code. May be anyone have other ideas?

推荐答案

如果您确定对象在缓存中,则Session.Get(id)不会命中数据库.可能最简单的方法是Evict返回的对象:

If you are sure that the object is in the cache, Session.Get(id) will not hit the db. It's probably easiest to do that and then Evict the object you get back:

Model m = Session.Get(id);
Session.Evict(m);

修改

我不清楚您是在谈论第一级缓存还是第二级缓存.上面的内容将从一级缓存中逐出.要从二级缓存中退出,请在SessionFactory上使用evict方法.

It is not clear to me if you are talking about the first-level cache or the second-level cache. The above will evict something from the first-level cache. To evict from the second-level cache, use the evict method on SessionFactory.

根据评论进行编辑

在这种情况下,您可以尝试Session.Load:

In that case, you might try Session.Load:

Model m = Session.Load(id);
Session.Evict(m);

如果m在缓存中,则Session.Load将返回您可以退出的实例.如果不是,它将返回一个代理(没有数据库命中).我的测试表明,如果您尝试逐出代理服务器,则Session.Evict不会抛出异常,因此应该可以.

If m is in the cache, Session.Load will return the instance which you can evict. If not it returns a proxy (no db hit). My tests suggest that Session.Evict will not throw if you try to evict the proxy, so this should work.

这篇关于NHibernate逐出ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆