【发布时间】:2018-06-02 06:31:13
【问题描述】:
我有一个场景,我有多个用户(一次大约 50 个)连接到一个表,所有用户都不断地对已经存在的行进行更改。我需要做的是总是以某种方式显示数据库的实时视图。
拥有表的缓存副本不是一个有效的选择,因为所有用户都需要立即查看所有更改。
当我第一次加载我正在使用的数据库时
mydtadp = new MySqlDataAdapter();
bindingSource1 = new BindingSource();
table = new DataTable();
MySqlConnection MyConn = new MySqlConnection(MyConnection);
MyConn.Open();
mydtadp.SelectCommand = new MySqlCommand("SELECT * FROM `Appointments`", MyConn);
cmbl = new MySqlCommandBuilder(mydtadp);
mydtadp.Fill(table);
bindingSource1.DataSource = table;
dataGridView1.DataSource = bindingSource1;
但是,当另一个用户进行更改时,这不会更新本地 DataGridView 以反映更改。在网上搜索后,我尝试将VirtualMode 属性设置为true。仍然没有运气。
接下来,我创建了一个每秒滴答一次的计时器,它会调用
dataGridView1.Refresh();
不过,当另一个用户更新数据库时,更改不会反映在本地 DGV 上。我发现另一篇文章建议尝试
bindingSource1.ResetBinding(false);
我把它放在我的计时器上,仍然没有更新。
我在MDSN 上找到一篇文章,建议我尝试在计时器函数中再次调用mydtadp.Fill(table); 函数。一样。
我唯一能做的就是保存当前选定行的索引,然后完全重新加载数据集,然后重新选择该索引。但是,这似乎很笨拙,必须有更好的方法来做到这一点。这种方法似乎是一种不好的做法,而且它的效果不是很好,只要计时器滴答作响,DGV 就会闪烁,当用户移动光标时,datagridview 需要几秒钟才能赶上用户。当用户对一行进行更改时,每次击键都需要一个完整的计时器滴答来更新。
【问题讨论】:
-
您尝试的大部分内容都是无用的,因为它与数据库没有连接。如果您想与数据库保持同步,那么您必须继续查询数据库,即在您的数据适配器上调用 Fill。最好的选择是在相关表中有一列包含上次修改的日期和时间。这样,您可以只检索自上次检索后发生更改的记录,并将数据传输保持在最低限度。
-
这也意味着您的
DataTable中已经存在并绑定到您的DataGridView的任何记录都不会被丢弃,因此您网格中的任何选择都将被保留。您所要做的就是检索新记录并刷新更新的记录。不会触及任何未更改的记录,即大部分数据。 -
目前尚不清楚重新加载整个表并重建输出是否“足够快”,或者此处进行一些优化是否实用且可取。多少数据? DGV 进行增量更改有多容易?
-
这是您的架构的问题。创建双工 WCF 服务来处理数据库更新请求。该服务将在更新完成后回拨用户。
-
还有一件事:避免任何特定于数据库的解决方案,保持通用性。此外,避免任何“轮询”或“拉”(来自客户端)解决方案,并优先考虑“推”(来自服务器)解决方案。从您帖子中的标签来看,我假设您正在谈论一个桌面应用程序 (
WinForms),这使得WCF绰绰有余并且适合您的用例。SignalR可能会起作用,尽管它有点矫枉过正,更适合“流式传输” ASP.NET 应用程序。
标签: c# mysql data-binding datagridview