2

我使用两个存储过程,它们返回具有相同结构的数据(相同类型的记录列表)。

我两次调用我的方法 Execute(ISession session)。第一个存储过程的第一次(它返回正确的 6 行列表)。第二次 - 对于第二个存储过程(它返回 11 行的列表,但前 6 行来自覆盖正确行的第一个请求)。

我发现 对搜索结果的 NHibernate 缓存的影响,包括映射为公式的计算值(例如排名)

但我不能将它用于 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;
}
4

2 回答 2

3

我将尝试回答这个问题,因为我想我对正在发生的事情有预感,我想让你走上正确的轨道。我在这里做了很多假设,所以如果我的猜测完全错误,请不要对我太苛刻。

感觉就像您正在尝试使用 NHibernate 作为一种工具来简单地将行转换为对象。相反,NHibernate 是一个在您的面向对象领域模型和您的关系数据库领域模型之间进行转换的工具。它所做的更多只是将行变成对象。特别是,您在这里遇到的 NHibernate 功能是 NHibernate 如何确保在单个 NHibernate 会话中,表示单个实体的数据库中的单个行将对应于对象的单个实例。它使用其一级缓存来完成此操作。

假设您有两个查询,QueryA 和 QueryB。这些查询的构造使得它们每个都从单独的表 TableA 和 TableB 中提取,因此它们实际上代表了单独的实体。然而,查询也以某种方式构建,以便结果在 NHibernate 中看起来像同一个实体。如果 QueryA 和 QueryB 碰巧返回了一些相同的 id,那么 NHibernate 会将它们组合到同一个实例中,所以当你运行 QueryB 时,你会看到来自 QueryA 的一些结果重复。

那么我们该如何解决呢?

快速而肮脏的解决方法是为这两个查询中的每一个使用不同的会话,或者session.Clear()在它们之间抛出一个。更合适的解决方法是更改​​这些命名查询,以便它们实际上返回两个不同的实体。

于 2013-08-28T04:21:48.317 回答
1

我有同样的问题,首先我解决了这个问题,session.Clear()但是这个解决方案导致了另一个错误。我阅读了 Daniel 的响应,我提供的这个响应是为了检测问题出在存储过程中,存储过程没有返回唯一标识符,当我使用 nhibernate 映射 ID 时产生了错误。

于 2016-05-17T20:24:22.597 回答