1

我有一个正在批量处理的 Item 实体列表,如下所示:

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

问题是,同一个 itemId 可能会在 ItemIdList 中列出多次,所以删除后,我再次尝试加载该项目,加载行失败并出现错误

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?

我的 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);
    }
4

1 回答 1

2

我还没有看到您的删除方法,但是由于您声明这些项目是“批量”完成的,我假设您等到所有内容都被删除后才刷新。

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

解决此问题的一种简单方法是将 ItemIdList 设置为一个集合(如 HashSet)。这将防止出现重复的 ID,并且应该可以解决问题。

另一方面,如果您尝试删除 id 列表中的所有实体,则有比从数据库中一次读取每个实体然后删除它们更有效的方法。

于 2012-08-17T19:11:30.883 回答