存储一个ObjectContext
在会话状态中,我认为不是一个好的实践,因为该类旨在封装工作单元模式 - 您加载一些数据(实体),修改它们,提交您的更改(由UOW),然后就完成了。 UOW 对象并非旨在或设计为长期存在的。
也就是说,它can要在不造成任何重大灾难的情况下完成,您只需确保了解幕后发生的事情即可。请继续阅读如果您打算这样做,这样您就知道自己将面临什么并意识到权衡。
我假设 Session 对象已完成并在用户会话过期时设置为垃圾回收,因此该实例将被正确处理。
这实际上是不准确的,或者至少看起来是基于其措辞方式。会话到期/注销不会立即导致任何项目被处置。他们会最终被最终确定/处置,但这取决于垃圾收集器,您无法控制它何时发生。这里最大的潜在问题是,如果您碰巧手动打开了连接ObjectContext
,它不会自动关闭 - 如果你不小心,你可能最终会泄漏数据库连接,这是常规单元测试/集成测试/实时测试无法发现的。
对象上下文将处理的数据量并不大,并且不会对我们像样的服务器硬件造成问题,因为随着时间的推移缓存和相对较少的并发用户。
请记住,增长是无限的。如果某个特定用户决定连续 12 个小时使用您的网站并整天运行不同的查询,那么上下文将会变得越来越大。一个ObjectContext
没有自己的内部“垃圾收集”,它不会清除长期未使用的缓存/跟踪实体。如果您根据您的用例确定这不会成为问题,那么很好,但应该困扰您的主要问题是您缺乏control的情况。
另一个问题是线程安全。ObjectContext
不是线程安全的。会话访问通常是序列化的,因此一个请求将阻塞等待其会话状态,直到同一会话的另一请求完成。但是,如果有人决定稍后进行优化,特别是页面级只读会话的优化,请求将不再持有独占锁,并且最终可能会遇到各种竞争条件或重入问题。
最后但并非最不重要的当然是多用户并发问题。一个ObjectContext
永远缓存其实体,直到它被处置。如果另一个用户自己更改相同的实体ObjectContext
,第一个的所有者ObjectContext
will never了解这一变化。这些过时的数据问题可能非常难以调试,因为您实际上可以看到查询进入数据库并返回新数据,但是ObjectContext
将用缓存中已有的旧数据覆盖它。在我看来,这可能是避免长期存在的最重要原因ObjectContext
实例;即使您认为您已对其进行编码以从数据库中获取最新数据,ObjectContext
会认为它比你聪明,然后把旧实体还给你。
如果您了解所有这些问题并已采取措施缓解这些问题,那就好了。但我的问题是,为什么您认为会话级ObjectContext
这是个好主意吗?创建一个ObjectContext
这确实是一个非常便宜的操作,因为元数据是为整个 AppDomain 缓存的。我敢打赌,要么你错误地认为它很昂贵,要么你试图在几个不同的网页上实现复杂的有状态进程,而后者的长期后果比任何特定的后果都要糟糕得多简单地放置一个可能会造成的伤害ObjectContext
进入会话。
如果你无论如何都要继续做这件事,只要确保你这样做是出于正确的理由,因为没有太多充分的理由这样做。但是,正如我所说,这绝对是可能的,并且您的应用程序不会因此而崩溃。
Update- 对于任何其他考虑对此进行否决的人,因为“同一会话上的多个请求可能会导致线程安全问题”,请阅读底部ASP.NET 会话状态概述文档。这不仅仅是个人访问序列化的会话状态;任何获取会话的请求都会对该会话保留独占锁,直到整个请求完成后才会释放该锁。除了我上面列出的一些优化之外,在默认配置中不可能有两个同时请求持有对同一会话本地实例的引用。ObjectContext
.
我仍然不会存储ObjectContext
由于上面列出的几个原因,它处于会话状态,但这不是线程安全问题,除非您将其设为一个。