NHibernate - KeyNotFoundException:字典中不存在给定的键
更新:我已经解决了这个问题
我有以下代码块,它最终应该更新
if (session.Contains(entity))
{
session.Evict(entity);
}
在 Session.Evict(entity) 上出现错误并出现 KeyNotFoundException 的记录,以及以下内容信息:
字典中不存在给定的键。
我误解了什么吗?我假设如果 session.Contains(entity) 为 true,那么密钥应该存在,因此 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
Update: I have fixed this issue
I have the following block of code which should ultimately update a record
if (session.Contains(entity))
{
session.Evict(entity);
}
which errors on Session.Evict(entity) with a KeyNotFoundException, and the following message:
The given key was not present in the dictionary.
Am I misunderstanding something? I assume if session.Contains(entity) is true, then the key should exist and therefore session.Evict() should work as expected?
Stack trace is as follows:
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
事实证明,Equals() 方法比较不正确,它正在检查对象上不属于复合键一部分的附加属性的相等性。
即
其中 DefaultEntry 是一个属性。
It turns out that the Equals() method was comparing incorrectly, it was checking the equality of an additional property on the object which was not part of the composite key.
i.e.
Where DefaultEntry is a property .
这可能是NH如何识别实体的问题。它可能使用与
Evict
中不同的方法来查找Contains
中的实体。如果您使用复合 ID,它将使用实体本身的实例作为键类型,除非您实现了表示复合 ID 的另一个类。
Equals
和GetHashCode
对于比较复合键也很重要。它需要比较密钥的属性。要找到实际原因,您可以调试 NH 代码,或者至少查看堆栈跟踪(将其粘贴到您的问题中)。
It may be an issue of how NH identifies the entity. It may use a different method to find the entity in
Contains
as inEvict
.If you use a composite ID, it uses instances of the entity itself as key type, unless you implemented another class which represents the composite id.
Equals
andGetHashCode
are additionally important to compare the composite key. It needs to compare the properties of the key.To find the actual reason, you could debug the NH code, or at least take a look into the stack trace (paste it to your question).
据我的理解和猜测,如果您的
实体
的PK是0
,您的实体不需要被驱逐,因为尚未链接到数据存储。如果是这样,您可以检查 && 中的
ID != 0
与会话。包含。to my understanding and guess, if the PK of your
entity
is0
your entity does not need to be Evicted because is not linked yet to the data storage.If so, you could check
ID != 0
in && with the session.Contains.