我希望把dbContext的生命周期与会话的生命周期绑定在一起,例如能够在多个请求中提交或放弃dbcontext上的一组更改。
是否有其他更好的方法来实现这一点?如果没有,什么机制适合创建和处理这些上下文?我正在考虑具有会话结束清理的静态哈希表,但也许我做得不对。我还考虑过只保留那些需要在多个请求中工作的上下文,并将其余的保留在每个操作中。有什么建议吗?
我希望把dbContext的生命周期与会话的生命周期绑定在一起,例如能够在多个请求中提交或放弃dbcontext上的一组更改。
是否有其他更好的方法来实现这一点?如果没有,什么机制适合创建和处理这些上下文?我正在考虑具有会话结束清理的静态哈希表,但也许我做得不对。我还考虑过只保留那些需要在多个请求中工作的上下文,并将其余的保留在每个操作中。有什么建议吗?
以下SO帖子非常优雅地回答了这个问题:
StructureMap CacheBy InstanceScope.HttpSession not working
基本上,魔法来自以下代码(适应您的问题和较新的StructureMap
语法):
ObjectFactory.Initialize(factory => {
factory.For<MyContext>()
.CacheBy(InstanceScope.HttpSession)
.Use(new MyContext(_myConnectionString));
});
然后,在您的控制器中,只需使用以下代码创建该对象的实例:
var db = ObjectFactory.GetInstance<MyContext>();
由于您通过StructureMap
设置了IoC(控制反转)实例的范围为HttpSession
,只要会话保持不变,每次检索到的上下文都应该是相同的。
然而,请注意,特别是对于DbContext
对象来说,这通常是一个非常糟糕的想法 - 因为您正在将一个状态跟踪对象与无状态环境混合在一起,很容易陷入一个错误事务或者对象状态异常的状态,导致你需要刷新你的会话才能继续进行数据库调用。
DbContext
对象通常被设计为非常轻量级和可丢弃的。让它们在作用域之外死亡基本上是可以接受的。
public MyController(MyContext context) { }
,从而使用相同设置生成本地副本。但是,为了帮助发布者实施该方案,我需要编写一整个系列的博客文章和代码示例,这似乎不适合在此论坛上讨论。因此,提供简单的答案可能存在一些不完美之处,但仍然可行。 - Troy Alford理论上,您可以将上下文存储到会话字典中,并在每个控制器中访问它。但是,您可能会遇到一些线程问题,因为在存储时所处的线程与检索时所处的线程不同。如果上下文不使用线程静态变量,则可能会起作用(但我不确定),否则不行。无论如何,这是糟糕的设计...在Web中没有人这样做...为什么要存储上下文?您可以以较低的价格在随后的HTTP请求中重新创建它。如果您需要跟踪属性更改,还有其他更适合Web的方法。