NHibernate, почему загрузка объекта после удаления вызывает исключение устаревшего состояния?

У меня есть список объектов 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 просто вернет ноль. Вот моя функция getById:

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

Почему SingleOrDefault просто не возвращает ноль?

Моя сущность 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 ответ

Решение

Я не видел ваш метод удаления, но так как вы заявляете, что эти элементы выполняются в "пакете", я буду предполагать, что вы будете ждать очистки, пока все не будет удалено.

Поскольку сброс не происходит до тех пор, пока вы не попытаетесь удалить все элементы, он все еще существует в базе данных. Поэтому, когда вы извлекаете элемент во второй раз, он думает, что он должен быть "удален", но вот, он все еще существует. Вот почему NHibernate считает, что государство "несвежее".

Одним из простых способов исправить это было бы использование ItemIdList (например, HashSet). Это предотвратит присутствие дубликатов и должно решить проблему.

С другой стороны, если вы пытаетесь удалить все объекты в списке идентификаторов, есть гораздо более эффективные способы, чем чтение каждого из них по одному из базы данных и последующее их удаление.

Другие вопросы по тегам