Entity framework 管理dbContext的生存期

Entity framework 管理dbContext的生存期,entity-framework,asp.net-mvc-4,dbcontext,Entity Framework,Asp.net Mvc 4,Dbcontext,我希望将dbContext的生存期与会话的生存期联系起来,例如,能够通过多个请求提交或放弃对dbContext上的一组突变的更改 有没有其他(更好的)方法来实现这一点?如果没有,那么创建和处理上下文的合适机制是什么?我正在考虑在会话结束时清理静态哈希表,但可能我做得都不对。我也在考虑只保留那些必须对多个请求进行处理的上下文,并保留每个操作的其余部分。有什么建议吗?在会话中使用DbContext live不是一个好的idia 当您有更多请求时,它将从数据库向上下文加载部分数据,这使得上下文更大,这

我希望将dbContext的生存期与会话的生存期联系起来,例如,能够通过多个请求提交或放弃对dbContext上的一组突变的更改


有没有其他(更好的)方法来实现这一点?如果没有,那么创建和处理上下文的合适机制是什么?我正在考虑在会话结束时清理静态哈希表,但可能我做得都不对。我也在考虑只保留那些必须对多个请求进行处理的上下文,并保留每个操作的其余部分。有什么建议吗?

在会话中使用DbContext live不是一个好的idia

  • 当您有更多请求时,它将从数据库向上下文加载部分数据,这使得上下文更大,这意味着内存问题

  • 与上下文中每个请求的DbContet相比,您不会更新数据,因为另一个用户(另一个会话)可能已经更新了您已经加载到上下文中的数据

  • 阅读此文,了解您的选择


    理论上,您可以将上下文存储到会话字典中,您可以在每个控制器中访问该字典。然而,您可能会遇到一些线程问题,因为在存储它时,您所处的线程与检索它时的线程不同。如果上下文不使用threadstatic变量,这可能会起作用(但我不确定),否则就不行。在任何情况下,这都是糟糕的设计…网络上没有人这样做…为什么要存储上下文?您可以在随后的http请求中以低廉的价格重新创建它。如果您需要跟踪属性的更改,还有其他更适合web的方法。

    通常在这种情况下,您需要将更改保存在临时存储中(如会话、cookie或数据库)。当您需要保存结果或查看新数据时,您将获得旧数据和更改,并构建新对象。更改可以存储为新对象或操作序列。应用更改时请小心,可能会发生数据冲突。对于cource use Context\Request

    您可以使用IoC(控制反转)容器来管理DBContext的生存期,例如StructureMap,步骤如下:

  • 安装适用于MVC 4的nuget软件包:

  • 阅读快速入门:

  • 设置DBContext的作用域:


  • 您还可以结合使用存储库和工作单元模式在多个请求中提交或放弃对dbcontext上的一组突变的更改。

    这个问题在下面的SO帖子中得到了相当优雅的回答:

    本质上,这种魔力来自以下代码(根据您的问题和
    StructureMap
    的较新语法进行了调整):

    ObjectFactory.Initialize(工厂=>{
    工厂
    .CacheBy(InstanceScope.HttpSession)
    .Use(新的MyContext(_myConnectionString));
    });
    
    然后-在控制器中,只需使用以下命令创建对象的实例:

    var db = ObjectFactory.GetInstance<MyContext>();
    
    var db=ObjectFactory.GetInstance();
    
    由于通过
    StructureMap
    设置的IoC(控制反转)已将实例配置为作用域为
    HttpSession
    ,因此只要会话相同,每次都应检索相同的上下文

    但是-请记住,对于
    DbContext
    对象,尤其是这通常是一个非常糟糕的想法-因为您将状态跟踪对象与无状态环境混合在一起,并且可以很容易地让自己进入一种状态,在刷新会话之前,一个错误的事务或一个处于奇数状态的对象可以阻止您进行任何进一步的数据库调用


    DbContext
    对象通常被设计为非常轻量级和一次性的。让它们退出范围基本上在你处理完它们之后就消失是完全可以的。

    有几件事,首先MVC没有会话的概念,MVC很大一部分是无状态的,即请求之间没有状态。其次,我个人认为,无论如何,保持DBcontext打开那么长时间是一个非常糟糕的主意,因为跟踪的对象越多,它的速度就越慢。这意味着你的用户在网站上停留的时间越长,你的用户体验就会越差。嗨,谢谢你的反馈。你能建议另一种解决方法吗?此外,我相信会议仍然可以发挥相当重要的作用。购物车、保持登录等都是基于会话的——或者至少,我认为是这样。如果您使用的是IOC容器,您可以将上下文的生存期设置为每个web请求。这样,如果您在同一请求的多个位置使用上下文,您将使用同一个上下文实例。@Martijn通常使用MVC,我们处理事情的方式有点不同,例如使用Auth,我们使用cookie来维护状态,这会产生持久登录的错觉。对于DBcontext,我建议将部分模型传递到视图,直到其完成,或者将该部分保存到数据库中。如果你对为什么EF会在很多跟踪项目上表现缓慢感兴趣,请查看我在这里的帖子:我知道它的缺点。然而,我正在寻找合适的解决方案。无论是将数据表复制到暂存表,还是使数据库模型难以置信地更加复杂——更不用说解决方案中的冲突解决问题(链接问题中的解决方案2),还是在会话中而不是dbcontext中存储可能复杂的对象,对我来说都不是一个好主意。谢谢!你能给我一些其他更合适的方法的提示吗?1)最简单的方法。在json中序列化ViewModel的副本并将其放入隐藏字段中。发布页面时,您将从json反序列化旧的ViewModel,并将其与用户修改的ViewModel进行比较。您执行比较的方式取决于您的需要。2) 从数据库中检索数据,创建新上下文的数据,
    var db = ObjectFactory.GetInstance<MyContext>();