.net 实体框架-保持数据库上下文打开与持续重新创建

.net 实体框架-保持数据库上下文打开与持续重新创建,.net,vb.net,entity-framework,.net,Vb.net,Entity Framework,我有一个相当简单的Winforms/Entity Framework(v6)程序: 查询数据库以填充表单元素 用户单击后,重新查询数据库以获取相关信息 对该信息执行计算并将其显示给用户 作为一名EF新手,我试着按照我在网上找到的例子,并提出了一些相当简单的填充/查询方法,大致如下: Private Sub Form1\u Load(发送方作为对象,e作为事件参数)处理MyBase.Load 使用ctx作为新的髓质 终端使用 端接头 私有子cboVal1\u SelectedIndexChange

我有一个相当简单的Winforms/Entity Framework(v6)程序:

  • 查询数据库以填充表单元素
  • 用户单击后,重新查询数据库以获取相关信息
  • 对该信息执行计算并将其显示给用户
  • 作为一名EF新手,我试着按照我在网上找到的例子,并提出了一些相当简单的填充/查询方法,大致如下:

    Private Sub Form1\u Load(发送方作为对象,e作为事件参数)处理MyBase.Load
    使用ctx作为新的髓质
    终端使用
    端接头
    私有子cboVal1\u SelectedIndexChanged(发送方作为对象,e作为事件参数)处理cboVal1.SelectedIndexChanged
    使用ctx作为新的髓质
    终端使用
    端接头
    私有子按钮(发送者作为对象,e作为事件参数)处理MyButton。单击
    使用ctx作为新的髓质
    终端使用
    端接头
    

    我所发现的是,似乎使我的程序变慢的部分(如果我在这方面有错误,请纠正我——正如我所说,我是一个新手)是因为我每次使用时都在重新建立一个新的DB连接:

    Using ctx As New MyEntities
        ...
    End Using
    
    在我的代码中

    所以,我想做的是让一个表单级变量
    ctx作为MyEntities
    ——在表单加载时建立连接,在表单关闭时关闭连接,并在整个过程中使用相同的连接。。。大致如下:

    Dim ctx作为MyEntities
    私有子表单1_Load(发送方作为对象,e作为事件参数)处理MyBase.Load
    ctx=新髓质
    端接头
    私有子cboVal1\u SelectedIndexChanged(发送方作为对象,e作为事件参数)处理cboVal1.SelectedIndexChanged
    端接头
    私有子按钮(发送者作为对象,e作为事件参数)处理MyButton。单击
    端接头
    Private Sub-Main_FormClosing(ByVal sender作为对象,ByVal e作为System.Windows.Forms.FormClosingEventArgs)处理Me.FormClosing
    ctx.Dispose()
    ctx=无
    端接头
    

    当我以这种方式工作时,它似乎大大提高了速度,我意识到它让我有可能对数据库进行错误的更改,但这是一个小项目,不做任何更新-只是查询。。。这是一种合理的解决方案还是一种危险的做法?

    数据库连接通常会被汇集到一个连接池中,几乎任何现代查询工具都可以使用。这看起来很像线程池;将打开一定数量的连接,并且无论何时创建新上下文并请求连接,都将以独占方式使用其中一个现有连接。当上下文被释放时,连接不会被关闭,它只会返回到连接池

    因此,没有必要尝试手动保持上下文长时间处于活动状态。仅在单个操作中使用它们


    当然,如果您明确不希望发生连接池,可以禁用连接池,但很少有理由这样做。

    一般来说,您应该以某种工作单元的方式使用DBContext,否则,由于DB context缓存实体,您的数据可能会过时,例如,如果执行两次相同的查询,它只会命中数据库一次。我广泛使用了EF,从未发现以这种方式使用上下文会很昂贵。我会做更多的调查,看看你们的速度有多慢。我也很好奇重新创建DBContext继承类是否代价高昂。我之前已经设置了一个存储库,其中repo中的每个函数都使用自己的DBContext实例。似乎没有任何问题,但该应用程序的数据密集度不是很高。请看这篇关于用EF实现工作模式的文章:如果你不需要改变你加载的数据(并把它写回数据库),你应该考虑对你的上下文进行跟踪跟踪(CTX.CONTION,AutoDebug更改= false)。这会给你带来显著的性能提升。这是一个很棒的建议,@StephanKeller!-我会马上调查的!!!谢谢,@BenRobinson&@async你们都在建议工作单元(感谢链接…我以前从未实现过这种模式,所以感谢你们的建议!!!)-现在也开始研究!谢谢,Servy!!!!-所以,要理解,您的意思是,我的第一个解决方案并不像我想象的那样昂贵,因为该连接将始终保持打开状态,并一直保留在池中直到应用程序结束,我理解正确吗?