我正在开发基于winforms和EF的桌面应用。
目前我对EF和架构有一些问题:
-
Syncronizing数据。有多个表单,每个表单使用它自己的数据库上下文实例。当数据更新的一种形式,我需要手动更新它的其他形式。有很多非灵活的回调和复制粘贴来刷新数据。
-
有一些计算运行在客户端和更新大量的记录。有时用户需要保存它,并与EF它需要很长时间。因此,它也在单独的上下文中运行,这样与其他实体的工作就不会受阻
-
有绑定实体的DataGridViews,
DbSet<T>.Local
和DbSet<T>.ToList()
有令人烦恼的问题。当gridview中的数据被保存时,它有时不会在其他地方更新。
我正在寻找任何最佳实践和灵活的模式,可以在那里使用。同时,也期待听到那些解决了同样问题的人的来信。
谢谢
这是我过去所做的(绝不是"最佳实践",但它对我有效,所以在这里开始):
-
使用一种"访问者模式"。有一个类,您的表单(或呈现器,或您使用的任何模式)订阅它,表明它们希望收到更改通知。然后在你的
SaveChanges()
上,你沿着ChangeSet
走,通知那些要求它的各方。我通过表单/演示器只订阅某些类型的更改来优化这一点,并且我将其批量提供给他们。每个表单对这些数据做他们想做的任何事情(从存储中刷新当前实体,检查显示在网格上的实体,等等)。还有,我在每个记录上都有一个
DateTime
成员(在SaveChanges
上自动填充)和一个特殊的表,其中包含每个主要可编辑记录集合的记录(全局考虑,"客户","发票"等),其DateTime
是上次更新这些记录的时间。如果需要,我可以用计时器进行轮询(我将其用于应用程序间通信,而不是用于当前应用程序中表单之间的通信)。 -
根据你的需要,在一个线程上做所有的改变可能对你有用。如果你的计算真的需要很长时间(或者在
SaveChanges
上设置并发检查),那么你可能想要设置软锁(你在应用程序中控制它们,禁用Save
按钮,或者网格的可编辑性,或者其他什么),这样用户就不能保存在该线程上被修改的记录,但是再一次,这取决于你的UI/UX偏好或要求。 -
我不直接绑定到
DbSet
(更不用说Local
,如果你正在使用几个上下文),我有一个集合,我绑定到。 解决"异地数据未更新"问题
PS:不是官方的或任何东西,但这个链接可能是一个有趣的阅读来管理你的DbContext
的生命周期(这可能是或可能不是原来的问题):http://mehdi.me/ambient-dbcontext-in-ef6/(免责声明:我不使用他的"dbcontextscopes",只是指向这个链接的文本阅读,我不知道他的代码是否会好)