【发布时间】:2021-07-07 20:48:09
【问题描述】:
我有一个 VB WinForms 项目,我们使用 Entity Framework 6 代码优先。我知道在 Web 应用程序中限制 dbContexts 的生命周期(我们通过存储库类间接使用)是理想的,但我最近了解到,通常,对于 WinForms 项目,您应该在表单的生命周期内保留一个 dbContext .
假设我有 ClassA 类和 ClassB 类,并且所有 ClassA 对象都有一个可选的 ClassB 对象(以及 EF6 用作外键的相关“ClassBId”属性)。我们有一个表单 ClassAForm 供用户编辑和查看 ClassA 对象,这自然会显示有关其 ClassB 对象的一些信息;这个 ClassB 应该是 ClassA 独有的,但也可以在其他形式上查看。此表单上有一个按钮可以打开另一个表单 ClassBForm,它允许用户编辑和查看 ClassB 对象。 ClassBForm 不是模态的,目前不向生成它的 ClassAForm 传递任何内容,尽管 ClassAForm 确实有 ClassBForm 中的事件的侦听器。
因此,据我了解,ClassAForm 将获得它自己的长期存在的 dbContext 对象,它会在表单生命周期内保留该对象; ClassBForm 将获得它自己的 dbContext 对象。因此,如果我对 ClassBForm 的 dbContext 中的 ClassB 对象进行更改,在 ClassAForm 的 dbContext 版本的 ClassB 对象中查看这些更改的理想方法是什么,其中 ClassB 可能是 ClassA 的导航属性?
我可以想到一些解决这个问题的方法,但我不确定最佳做法是什么;也有可能(我希望有人会提到)我的整个理解或框架是不正确的。
(可能的)我想到的解决方案:
- 忽略 MS 的建议,只为特定的 DB 交互保持 dbContexts 活动;在每次更新事件和表单加载时刷新 dbContext(s),就像它是一个 Web 应用程序一样
- 在表单之间传递相同的 dbContext(s)(在我的存储库类的构造函数中,在我的例子中)并且很少处理它(不理想 - 数据库由几个服务更新)
- 在我的数据层中手动附加/分离并将更新标记为已更新
- 通过事件将更新的对象传递给其他表单,并在每个上下文中手动更新对象(我认为当我需要保存更改时这会遇到问题?)
【问题讨论】:
-
在表单的整个生命周期中保留一个 dbContext 几乎是您不应该做的事情。这是我必须在桌面应用程序中学习数据库编程的第一堂课(早在 EF 存在之前)。您需要使用 dbContext 将 SELECT 与 UPDATE 分开。在这种情况下如何防止静默数据覆盖是真正的问题。
-
@glenebob 我也这么认为,但 MS 文档建议 WindowsForms 不然:docs.microsoft.com/en-us/ef/ef6/fundamentals/…(第二个要点)......但它似乎并不真正有意义有限的场景,表单之间的交互很少。我将带着短暂的生命去。我有应该防止有意义的静默覆盖的业务规则和 UI 层规则(这是一个只有 1-2 个安装位置的内部应用程序)。谢谢!
-
我在一个项目中遇到了同样的问题。我之前的开发人员在每个课程中都使用了许多上下文。但好的是每个 DB 函数都单独工作,使用相同的 DB 对象,但按需打开和关闭连接。请记住,保持上下文活跃并不一定是坏事,但保持连接打开得很好。
标签: .net vb.net winforms entity-framework-6