我想将 dbContext 的生命周期与会话的生命周期联系起来,例如,能够通过多个请求提交或放弃对 dbcontext 上的一组突变的更改。
有没有其他(更好的?)方法可以做到这一点?如果不是,那么创建和处理上下文的合适机制是什么?我正在考虑在会话结束时进行清理的静态哈希表,但也许我做错了。我也在考虑只保留那些必须处理多个请求的上下文,并保留每个操作的其余部分的想法。有什么建议吗?
我想将 dbContext 的生命周期与会话的生命周期联系起来,例如,能够通过多个请求提交或放弃对 dbcontext 上的一组突变的更改。
有没有其他(更好的?)方法可以做到这一点?如果不是,那么创建和处理上下文的合适机制是什么?我正在考虑在会话结束时进行清理的静态哈希表,但也许我做错了。我也在考虑只保留那些必须处理多个请求的上下文,并保留每个操作的其余部分的想法。有什么建议吗?
您可以使用IoC(控制反转)容器来管理 DBContext 的生命周期,例如StructureMap,步骤如下:
为 MVC 4 安装 nuget 包:http: //nuget.org/packages/StructureMap.MVC4
设置 DBContext 的范围:http: //docs.structuremap.net/Scoping.htm
您还可以使用存储库和工作单元模式的组合来提交或放弃对多个请求的 dbcontext 上的一组突变的更改。
这个问题在下面的 SO 帖子中得到了相当优雅的回答:
StructureMap CacheBy InstanceScope.HttpSession 不起作用
本质上,魔法来自以下代码(针对您的问题和更新的语法进行了调整StructureMap
):
ObjectFactory.Initialize(factory => {
factory.For<MyContext>()
.CacheBy(InstanceScope.HttpSession)
.Use(new MyContext(_myConnectionString));
});
然后 - 在您的控制器中,只需使用以下命令创建对象的实例:
var db = ObjectFactory.GetInstance<MyContext>();
因为您的 IoC(控制反转)设置通过StructureMap
已将实例配置为范围HttpSession
,所以只要会话相同,您就应该每次检索相同的上下文。
但是 - 请记住,DbContext
特别是对于对象,这通常是一个非常糟糕的主意- 因为您将状态跟踪对象与无状态环境混合在一起,并且很容易让自己进入一个状态,其中一个错误的交易或一个对象处于奇怪状态可能会阻止您进行任何进一步的数据库调用,直到您刷新会话。
DbContext
物体通常被设计成非常轻巧和一次性的。完全可以让它们退出范围并在您完成它们后立即死亡。
让 DbContext 与会话一起生活并不是一个好的 idia。
当您有更多请求时,它会将部分数据从数据库加载到上下文中,这会使上下文变得更大,这意味着内存问题,
并且与上下文中的每个请求相比,您不会更新数据,因为另一个用户(另一个会话)可能已经更新了您已经加载到上下文中的数据。
并阅读此内容以供您选择,
通常在这种情况下,您需要在临时存储中保留更改(如会话或 cookie 或数据库)。当您需要保存结果或查看新数据时,您会获取旧数据和更改并构建新对象。更改可以存储为新对象或动作序列。应用更改时要小心,可能会发生数据冲突。当然使用 Context\Request
理论上,您可以将上下文存储到可以在每个控制器中访问的 Session 字典中。但是,您可能会遇到一些线程问题,因为在存储它时,您与检索它时处于不同的线程中。如果上下文不使用线程静态变量,这可能会起作用(但我不确定),否则不会。无论如何,这是一个糟糕的设计......网络中没有人这样做......为什么要存储上下文?您可以在随后的 http 请求中以低廉的价格重新创建它。如果您需要跟踪属性的变化,还有其他更适合网络的方法。