附加到多个DbContexts的实体的引用相等性?

时间:2018-04-04 10:27:33

标签: c# asp.net-core entity-framework-core

从({附加到] DbContext dbContext1接收实体,然后手动将此实体附加到DbContext dbContext2时,将从这两个实体中的任何一个接收到的每个实体(代表相同的数据库对象)将来的上下文(例如作为查询结果)与首先提到的对象具有引用相等性?

我知道同一个数据库对象的实体总是具有一个DbContext范围的引用相等性,但是当将实体附加到多个DbContext时可以扩展吗?

背景:我有一个ASP.NET核心Web API应用程序,它不仅使用每个请求范围附带的DbContext,而且还有一个长寿命具有自己的DbContext的后台任务的范围。我想知道源自请求范围内的实体是否可以附加到长期存在的范围,以便后台任务也可以看到请求中这些实体的更改,而无需单独刷新这些实体。

1 个答案:

答案 0 :(得分:0)

没有。 EF在上下文中做了一些技巧,以确保您始终获得特定实体的相同实例(基本上,它创建一个对象缓存并且不创建新实例,除非它找不到现有实例缓存中该实体的实例)。但是,这是每个上下文。如果从上下文1中查询实体X,然后从上下文2中查询同一实体X并尝试将它们与x1 == x2进行比较,则它将返回false。

如果您需要参照完整性,唯一真正的选择是覆盖您的实体类上的EqualsGetHashCode==运算符。但是,这样做并非易事,并且非常很容易犯错误,要么会使等式检查过于贪婪或过于严格,导致错误的true / {{ 1}}结果。可以肯定的是,这是可行的;先做你的研究,确保你知道自己在做什么。微软documentation至少可以让你入门。

然而,这里更简单,更健壮的解决方案是简单地将两个上下文范围保持断开状态。在请求范围中执行您需要执行的操作,然后只需确保在执行任何操作之前,单个范围内的上下文始终从数据库重新加载。 documentation on handling concurrency conflicts应该让你很好地了解你需要做什么,因为这在技术上是一种并发形式。