Chr*_*rds 6 .net data-binding linq-to-sql winforms
这个一直困扰我一段时间.但我不是专家.这有点长......
我有一个带有Outlook样式UI的WinForms应用程序.可以说左侧窗格上有一个栏,允许您选择一个"屏幕",这是一个WinForms控件,比如客户屏幕,在右侧窗格中会出现一个客户列表(即客户)控制).我将其称为资源管理器界面.双击记录将在另一个窗口中显示非模态客户记录,就像在Outlook中打开电子邮件一样,我们称之为检查员.如果双击多个记录,您将获得多个检查员.
整个过程都是使用数据绑定完成的.客户列表控件上有一个BindingSource控件,客户检查器上有另一个控件.客户控制在其加载事件中新闻静态DataContext,并将简单的Linq-To-SQL查询的结果分配给BindingControl数据源属性.双击客户列表时,事件会查找记录,将其转换为Linq-To-SQL客户对象,并将其提供给客户检查器表单的构造函数.客户检查器获取客户对象并将其BindingSource控件的datasource属性分配给它.
由于BindingSource控件支持IBindingList,因此在单击"确定"按钮时,在此应用程序中调用EndEdit时,不会修改客户对象的内容.由于Linq to SQL实现了INotifyPropertyChanged接口,因此会更新客户列表.凉.
然而,当我想刷新客户列表的内容以获取其他用户所做的更改时,问题就出现了,我想每隔60秒就定期发生一次.如果我有一个计时器并在同一个datacontext上重新运行查询,则不会选择任何更改,因为Linq to SQL不希望压缩对datacontext控制下的数据所做的任何更改.奇怪的是,它针对数据库运行查询,但身份跟踪意味着只有从数据库返回的新客户对象才会添加到列表中.如果我新建了另一个datacontext,那么任何开放的客户检查员都不再使用相同的datacontext,因此未来对开放客户检查员的任何更改都不会反映在客户列表中.
基本上数据是陈旧的,因为我没有使用工作单元模式.所以(如果你还在我身边),问题是.
1.在这种情况下,我该如何使工作单元模式工作?ASP.NET很容易使用请求范围的datacontext,它很短暂,但在WinForms中?
2.在这种情况下,是否还有其他ORM可以更好地工作?NHibernate,EF,LLBLGEN等
我该怎么办呢?
并且.
4.如果我可以使Linq to SQL工作,那么任何人都在Linq to SQL部分类中实现IBindingList,这将避免我不得不使用IBindingSource控件.(我不确定我应该关心这个).
5.如果我可以使Linq to SQL工作,那么在SQL 2008中是否有任何使用SQL Notifications的方法,这样我可以在基础查询结果发生变化时得到通知,然后重新查询,而不是轮询.
谢谢!
PS我知道我可以使用
db.Refresh(System.Data.Linq.RefreshMode.KeepChanges, customers)
Run Code Online (Sandbox Code Playgroud)
但这会导致针对列表中每个客户的记录针对数据库运行查询.
我将重述您的问题以确保我已经理解它。
您有一个显示实体列表(LIST)的小部件。当您单击列表中的某个项目时,会出现另一个小部件,允许用户编辑该实体。当用户完成编辑实体时,他们的更改将提交到数据库,并且也应该反映在实体列表中。系统还应该定期获取其他用户对 LIST 中的项目所做的更改并更新 LIST。
如果这是正确的,我将忽略两个用户编辑同一实体的任何并发问题,因为这似乎不是您关心的问题,并将重点关注如何组织 UI 和工作单元。
您需要将列表中的实体与检查员正在编辑的实体分开。由检查员代表的业务流程是您的工作单元,每个实体一个单元。您的列表并不代表一个工作单元。它是所有先前提交的工作单元的组合工作的陈旧表示或时间点。您的 LIST 甚至不必直接处理您的实体,它可以保存 ID 或任何其他方式,以便您的检查员在用户单击它时从数据库获取底层实体。现在,您可以随时更新列表,因为您的检查员根本不与其共享实例。
为了向您的用户模拟他们通过检查器编辑实体时并使他们看起来绑定到同一事物,您有两种选择。
1) 列表仅与数据库中已提交的数据绑定。这很容易,当检查员将本地更改刷新回数据库并成功提交时,为检查员提供一种方法告诉列表自行更新。
2)列表绑定已提交数据+本地未提交数据。这有点困难,您需要公开列表上的方法,这些方法允许检查器胜过从数据库返回的数据,并用自己的本地脏数据覆盖它。