NHibernate - KeyNotFoundException:字典中不存在给定的键

发布于 2024-12-01 23:43:30 字数 1101 浏览 1 评论 0原文

更新:我已经解决了这个问题

我有以下代码块,它最终应该更新

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

維他命╮ 2024-12-08 23:43:30

事实证明,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 是一个属性。

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.

return obj != null
                   && obj is InstanceVersion
                   && this.Instance.Id == ((InstanceVersion)obj).Instance.Id
                   && this.Version == ((InstanceVersion)obj).Version
                   && this.DefaultEntry == ((InstanceVersion)obj).DefaultEntry;

Where DefaultEntry is a property .

初见你 2024-12-08 23:43:30

这可能是NH如何识别实体的问题。它可能使用与 Evict 中不同的方法来查找 Contains 中的实体。

如果您使用复合 ID,它将使用实体本身的实例作为键类型,除非您实现了表示复合 ID 的另一个类。 EqualsGetHashCode 对于比较复合键也很重要。它需要比较密钥的属性。

要找到实际原因,您可以调试 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 in Evict.

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 and GetHashCode 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).

八巷 2024-12-08 23:43:30

据我的理解和猜测,如果您的实体的PK是0,您的实体不需要被驱逐,因为尚未链接到数据存储。

如果是这样,您可以检查 && 中的 ID != 0与会话。包含。

to my understanding and guess, if the PK of your entity is 0 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文