NHibernate,为什么在删除后加载实体会导致陈旧状态异常?

时间:2012-08-17 18:40:45

标签: c# .net nhibernate staleobjectstate

我有批处理的Item实体列表,如下所示:

foreach (var itemId in ItemIdList)
{
    var item = getById(itemId); //load line
    if(item != null)
    {
      //...do some processing 
      delete(item)
    }
}

问题是,同一itemId可以在ItemIdList中多次列出,因此在删除之后,我尝试再次加载项目时,加载行会失败并显示错误< / p>

Unexpected row count: 0; expected: 1  (stale state exception)

我知道实体不再存在,但我希望我的get函数只返回null。这是我的getById函数:

var item = (from i in UnitOfWork.CurrentSession.QueryOver<T>()
                        where i.Id == id
                        select i
                        ).SingleOrDefault();

SingleOrDefault 为什么不返回null?

My Item实体只有一个自动生成的密钥,散列函数如下所示:

public override int GetHashCode()
    {
        int hashCode = 0;

        hashCode = hashCode ^ Id.GetHashCode();

        return hashCode;
    }

编辑:

这是我的删除方法

    public void Delete(T t) //T would be Item in this case
    {
       UnitOfWork.CurrentSession.Delete(t);
    }

1 个答案:

答案 0 :(得分:2)

我还没有看到你的删除方法,但由于你声明这些项目是在“批处理”中完成的,我假设你等到刷新,直到所有内容都被删除。

由于在您尝试删除所有项目之前不会发生刷新,因此它仍然存在于数据库中。因此,当您第二次检索该项时,它认为应该“删除”但是,它仍然存在。这就是为什么NHibernate认为状态是“陈旧的”。

解决这个问题的一个简单方法是让ItemIdList成为一个集合(如HashSet)。这样可以防止出现重复的ID,并解决问题。

另一方面,如果您试图删除ID列表中的所有实体,那么从数据库中读取每个实体,然后删除它们,会有更多有效的方法。