【发布时间】:2012-07-09 20:08:52
【问题描述】:
使用 NHibernate 进行条件查询时,我想从缓存中获取新结果而不是旧结果。
流程基本上是:
- 在 NHibernate 应用程序中查询持久对象。
- 从外部更改数据库条目(另一个程序,在 SSMS/MSSQL 中手动编辑等)。
- 查询持久化对象(查询代码相同),之前加载的对象应从数据库中刷新。
这是代码(对象名称略有更改):
public IOrder GetOrderByOrderId(int orderId)
{
...
IList result;
var query =
session.CreateCriteria(typeof(Order))
.SetFetchMode("Products", FetchMode.Eager)
.SetFetchMode("Customer", FetchMode.Eager)
.SetFetchMode("OrderItems", FetchMode.Eager)
.Add(Restrictions.Eq("OrderId", orderId));
query.SetCacheMode(CacheMode.Ignore);
query.SetCacheable(false);
result = query.List();
...
}
我添加了 SetCacheMode 和 SetCacheable 来禁用缓存。此外,NHibernate 工厂是使用配置参数 UseQueryCache=false 设置的:
Cfg.SetProperty(NHibernate.Cfg.Environment.UseQueryCache, "false");
无论我为查询或会话做什么,包括 Put/Refresh 缓存模式:NHibernate 都会在第二次调用查询时向我返回过时的对象,而没有外部提交的更改。 Info btw.:在这种情况下,过时的值是 Version 列的值(测试是否可以在保存之前检测到陈旧的对象状态)。但出于多种原因,我需要新的查询结果!
NHibernate 甚至会生成一个 SQL 查询,但它从不用于返回的值。
保持会话打开对于仅对脏列进行动态更新是必要的(也没有用于解决方案的无状态会话!);我不想在代码中到处添加 Clear()、Evict() 或类似的东西,特别是因为查询处于较低级别并且不记得以前加载的对象。悲观锁定会降低性能(多用户环境!)
有没有办法通过配置强制 NHibernate 直接向数据库发送查询并获得新的结果,而不是使用不需要的缓存功能?
【问题讨论】:
标签: nhibernate session caching