在C#(WPF.Net)中如何获取MySQL数据增删改的事件通知?
实现WPF .NET程序实时接收数据库变更通知的方案
针对监控数据库表增删改操作并实时通知WPF程序的需求,以下是几种可行的实现方案:
方案一:利用SQL Server原生Query Notifications(SqlDependency)
适合SQL Server环境,基于Service Broker实现实时通知,无需轮询。
- 先开启数据库Service Broker:
ALTER DATABASE YourDatabaseName SET ENABLE_BROKER;
- WPF程序中配置监听:
// 初始化全局SqlDependency SqlDependency.Start(YourConnectionString); private void RegisterTableDependency() { using (var conn = new SqlConnection(YourConnectionString)) { conn.Open(); // 注意:查询必须指定列名,不能用*,不能包含TOP、DISTINCT等特殊语法 using (var cmd = new SqlCommand("SELECT Id, Column1, Column2 FROM dbo.TargetTable", conn)) { var dependency = new SqlDependency(cmd); dependency.OnChange += (sender, e) => { // 切换到WPF UI线程处理通知 Application.Current.Dispatcher.Invoke(() => { // 执行更新UI、刷新数据等操作 MessageBox.Show("目标表已发生增/删/改操作"); // 重新注册监听(SqlDependency为一次性触发) RegisterTableDependency(); }); }; // 执行查询激活依赖 cmd.ExecuteReader(CommandBehavior.CloseConnection); } } }
注意:需确保数据库账号拥有VIEW SERVER STATE权限,且查询语句符合SqlDependency的语法要求。
方案二:触发器+日志表/消息队列
通用适配多数数据库,通过触发器记录变更,再由WPF程序获取通知。
- 创建变更日志表(SQL Server示例):
CREATE TABLE dbo.TableChangeLog ( LogId INT IDENTITY(1,1) PRIMARY KEY, TableName NVARCHAR(100) NOT NULL, ChangeType NVARCHAR(10) NOT NULL, -- INSERT/UPDATE/DELETE ChangeTime DATETIME DEFAULT GETDATE() NOT NULL );
- 给目标表创建触发器:
CREATE TRIGGER Trigger_TargetTable_Change ON dbo.TargetTable AFTER INSERT, UPDATE, DELETE AS BEGIN SET NOCOUNT ON; INSERT INTO dbo.TableChangeLog (TableName, ChangeType) VALUES ( 'TargetTable', CASE WHEN EXISTS(SELECT * FROM INSERTED) AND EXISTS(SELECT * FROM DELETED) THEN 'UPDATE' WHEN EXISTS(SELECT * FROM INSERTED) THEN 'INSERT' ELSE 'DELETE' END ); END
- WPF程序轮询日志表:
private readonly DispatcherTimer _changeTimer = new DispatcherTimer(); private DateTime _lastCheckTime = DateTime.Now; public void StartMonitoring() { _changeTimer.Interval = TimeSpan.FromSeconds(5); // 按需调整轮询间隔 _changeTimer.Tick += (sender, e) => { using (var conn = new SqlConnection(YourConnectionString)) { conn.Open(); using (var cmd = new SqlCommand(@" SELECT COUNT(*) FROM dbo.TableChangeLog WHERE ChangeTime > @LastCheckTime", conn)) { cmd.Parameters.AddWithValue("@LastCheckTime", _lastCheckTime); int changeCount = (int)cmd.ExecuteScalar(); if (changeCount > 0) { Application.Current.Dispatcher.Invoke(() => { MessageBox.Show($"检测到{changeCount}条数据库变更"); // 更新最后检查时间 _lastCheckTime = DateTime.Now; }); } } } }; _changeTimer.Start(); }
若追求更低延迟,可将日志表替换为消息队列(如MSMQ),触发器直接推送消息,WPF程序监听队列。
方案三:SQL Server Change Tracking
适合需要获取具体变更数据的场景,可精准追踪行级变更。
- 启用数据库和表的Change Tracking:
ALTER DATABASE YourDatabaseName SET CHANGE_TRACKING = ON (CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON); ALTER TABLE dbo.TargetTable ENABLE CHANGE_TRACKING WITH (TRACK_COLUMNS_UPDATED = ON);
- WPF程序查询变更记录:
private long _lastSyncVersion = 0; public void CheckTableChanges() { using (var conn = new SqlConnection(YourConnectionString)) { conn.Open(); using (var cmd = new SqlCommand(@" SELECT CT.SYS_CHANGE_OPERATION, CT.Id FROM CHANGETABLE(CHANGES dbo.TargetTable, @LastSyncVersion) AS CT", conn)) { cmd.Parameters.AddWithValue("@LastSyncVersion", _lastSyncVersion); using (var reader = cmd.ExecuteReader()) { while (reader.Read()) { string operation = reader["SYS_CHANGE_OPERATION"].ToString(); int rowId = (int)reader["Id"]; Application.Current.Dispatcher.Invoke(() => { MessageBox.Show($"行ID {rowId} 发生{operation}操作"); }); } } // 获取最新版本号,用于下次同步 using (var versionCmd = new SqlCommand("SELECT CHANGE_TRACKING_CURRENT_VERSION()", conn)) { _lastSyncVersion = (long)versionCmd.ExecuteScalar(); } } } }
可配合定时任务定期调用CheckTableChanges方法,实现准实时监控。
内容的提问来源于stack exchange,提问作者Francisco Lopez
相关产品推荐
相关产品推荐

