我使用两个存储过程返回具有相同结构的数据(相同类型的记录列表)。
我两次调用我的方法Execute(ISession session)。第一次存储过程(它返回正确的6行列表)。第二次 - 对于第二个存储过程(它返回11行的列表,但前6行来自覆盖正确行的第一个请求)。
我找到了 Impact on NHibernate caching for searches with results including calculated value mapped as a formula (e.g. rank)但我不能将它用于IQuery
任何想法或链接如何解决?
public dynamic Execute(ISession session)
{
var query = session.GetNamedQuery(QueryName)
.SetCacheable(false)
.SetCacheMode(CacheMode.Ignore)
.SetReadOnly(true);
var results = query.List<T>();
return results;
}
答案 0 :(得分:2)
我会采取措施来回答这个问题,因为我认为我对所发生的事情有所预感,我想让你走上正轨。我在这里做了很多假设,所以如果我的猜测完全错了,请不要太苛刻。
感觉就像是在尝试将NHibernate用作简单地将行转换为对象的工具。相反,NHibernate是一种在面向对象的域模型和关系数据库域模型之间进行转换的工具。只需将行转换为对象,它就会做得更多。特别是,你在这里绊倒的NHibernate功能是NHibernate如何确保在单个NHibernate会话中,表示单个实体的数据库中的单个行将对应于对象的单个实例。它使用它的第一级缓存来实现这一目标。
假设您有两个查询,QueryA和QueryB。构造了这些查询,以便它们分别从单独的表TableA和TableB中提取,因此它们实际上代表了单独的实体。但是,查询也以某种方式构建,以便结果看起来像NHibernate一样。如果QueryA和QueryB碰巧返回一些相同的id,那么NHibernate会将它们组合到同一个实例中,因此当你运行QueryB时,你会看到QueryA重复的一些结果。
那么我们该如何解决呢?
快速而肮脏的修复方法是为这两个查询中的每一个使用不同的会话,或者在它们之间抛出session.Clear()
。更合适的修复方法是更改这些命名查询,以便它们实际返回两个不同的实体。
答案 1 :(得分:0)
我遇到了同样的问题,首先我用session.Clear()
解决了问题但这个解决方案导致了另一个错误。我读了Daniel的回复,这个响应我用来检测问题是在存储过程中,存储过程没有返回唯一标识符,这在我用nhibernate映射ID时产生了错误。