NHibernate - KeyNotFoundException: данный ключ отсутствовал в словаре
Обновление: я исправил эту проблему
У меня есть следующий блок кода, который должен в конечном итоге обновить запись
if (session.Contains(entity))
{
session.Evict(entity);
}
какие ошибки в Session.Evict(entity) с KeyNotFoundException и следующее сообщение:
Указанный ключ отсутствует в словаре.
Я что-то не понимаю? Я предполагаю, что если session.Contains(entity) истинно, тогда ключ должен существовать и, следовательно, session.Evict() должен работать как ожидалось?
Трассировка стека выглядит следующим образом:
System.Collections.Generic.KeyNotFoundException : The given key was not present in the dictionary.
at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
at NHibernate.Engine.StatefulPersistenceContext.RemoveEntity(EntityKey key)
at NHibernate.Event.Default.DefaultEvictEventListener.OnEvict(EvictEvent event)
at NHibernate.Impl.SessionImpl.FireEvict(EvictEvent evictEvent)
at NHibernate.Impl.SessionImpl.Evict(Object obj)
at Core.Repository.NHibernate.Repository.NoIdRepository`1.Update(T entity) in NoIdRepository.cs: line 26
at Core.Tests.Repository.NHibernate.Repository.TestInstanceVersionRepository.Test_Saving_Data() in TestInstanceVersionRepository.cs: line 63
Ответы
Ответ 1
Оказывается, что метод Equals() сравнивался неправильно, он проверял равенство дополнительного свойства на объекте, который не был частью составного ключа.
то есть.
return obj != null
&& obj is InstanceVersion
&& this.Instance.Id == ((InstanceVersion)obj).Instance.Id
&& this.Version == ((InstanceVersion)obj).Version
&& this.DefaultEntry == ((InstanceVersion)obj).DefaultEntry;
Если DefaultEntry является свойством.
Ответ 2
Это может быть проблема того, как NH идентифицирует объект. Он может использовать другой метод для поиска объекта в Contains
, как в Evict
.
Если вы используете составной идентификатор, он использует экземпляры самого объекта как тип ключа, если только вы не внедрили другой класс, который представляет составной идентификатор. Equals
и GetHashCode
также важны для сравнения составного ключа. Он должен сравнить свойства ключа.
Чтобы найти фактическую причину, вы можете отлаживать NH-код или, по крайней мере, заглядывать в трассировку стека (вставьте его в свой вопрос).
Ответ 3
к моему пониманию и предположению, если PK вашего entity
0
, ваша сущность не должна быть высечена, поскольку еще не связана с хранилищем данных.
Если это так, вы можете проверить ID != 0
в && с session.Contains.