Fluent nhibernate 多用户环境中的NHibernate查询缓存

Fluent nhibernate 多用户环境中的NHibernate查询缓存,fluent-nhibernate,nhibernate-criteria,nhibernate-caches,Fluent Nhibernate,Nhibernate Criteria,Nhibernate Caches,对于我们的web应用程序(ASP.NET),我们使用Fluent NHibernate(2.1.2)和二级缓存,不仅用于实体,还用于查询(使用criteria API生成查询)。我们使用每请求会话模式和一个SessionFactory应用程序范围,因此缓存服务于所有Nhibernate会话 问题: 我们必须处理遗留数据库(Oracle)中每个用户对数据对象的不同“访问权限”——也就是说,视图约束每个用户返回数据的权限。 因此存在这样的情况,例如,我们的条件使用exact相同的查询查询相同的视图

对于我们的web应用程序(ASP.NET),我们使用Fluent NHibernate(2.1.2)和二级缓存,不仅用于实体,还用于查询(使用criteria API生成查询)。我们使用每请求会话模式和一个SessionFactory应用程序范围,因此缓存服务于所有Nhibernate会话


问题:

我们必须处理遗留数据库(Oracle)中每个用户对数据对象的不同“访问权限”——也就是说,视图约束每个用户返回数据的权限。 因此存在这样的情况,例如,我们的条件使用exact相同的查询查询相同的视图,但根据用户权限返回不同的结果集

现在,为了提高性能,将缓存提到的查询。但这给我们带来了一个问题,当查询第一次从用户A的操作触发时,它会缓存生成的ID,这些ID是用户A具有访问权限的ID。不久之后,用户B的一个操作触发了相同的查询,然后Nhibernate从第一个调用(来自用户A)中选择缓存的ID,并尝试获取相应的实体,用户B对这些实体没有访问权限(或者可能不是所有实体)。我们正在使用事件侦听器检查权限,因此在上述情况下,我们的应用程序会抛出一个访问权限异常


想法:

不缓存查询可能是解决此问题的一个选项。但在我们的应用程序中,性能显然是一个问题,所以真正需要的是缓存查询

我们甚至考虑过每个用户都有一个SessionFactory,每个用户都有一个缓存。但这显然对资源产生了影响,有点过分,老实说,这不是一个选择,因为 有些实体必须由多个用户(比如用户组)访问和操纵,从而在“单个缓存”中产生过时数据问题,等等。所以这是不可能的

什么是有效的解决方案?对于这种情况,是否有类似于“最佳实践”的做法?


创意:

因为我昨天被困在这里,看不到出路,我就睡了过去,今天我想出了一个“黑客”

当NHibernate通过查询文本和参数(“子句”)缓存查询时,我想到了一种方法,在查询的签名中“走私”一些依赖于用户的东西,因此 缓存每个用户的每个查询,但不会更改查询本身(关于查询结果)

所以“创造力”引导我这样做(示例代码):

这一行:

.Add(Expression.Sql(string.Format(“{0}={0}”,用户名)))

结果产生一个where子句,该子句的计算结果始终为true,但从Nhibernate的角度“更改”了查询,因此它按单独的“用户名”进行缓存

我知道,这有点难看,我对它不是很满意。 有人知道其他方法吗?

提前谢谢

string userName = GetCurrentUser();
ICriteria criteria = session.CreateCriteria(typeof (EntityType))
            .SetCacheable(true)
            .SetCacheMode(CacheMode.Normal)
            .Add(Expression.Eq("PropertyA", 1))
            .Add(Expression.IsNotNull("PropertyB"))
            .Add(Expression.Sql(string.Format("'{0}' = '{0}'", userName)));
return criteria.List();