如何填充类型化数据集、保持其同步以及在数据更改时接收更新

本文关键字:数据 更新 同步 填充 何填充 类型化 数据集 | 更新日期: 2023-09-27 18:20:22

因此,我正在开发一个应用程序,它可以作为一个大型专有应用程序的"助手",而我既没有该应用程序的源代码,也无权修改该应用程序。然而,专有应用程序确实将其所有数据存储在Microsoft SQL数据库(我相信是2008 R2或更高版本)中,我很清楚这些数据代表什么。我需要我的应用程序在添加、更新和删除数据时不断监控数据,然后自动对数据采取行动(例如发出警报)。

问题是找出接收其他应用程序对数据库所做更改的最佳方法,因为我不想错过任何一次。

以下是我迄今为止所做的

  1. LINQ to SQL:据我所知,每次运行查询时,我都会收到一组新的数据,但我无法仅接收更改或收到更改通知
  2. 使用数据集的类型化数据集。加载:

    using (IDataReader reader = dataSetInstance.CreateDataReader())
    {
        dataSetInstance.Load(reader, LoadOption.OverwriteChanges, dataSetInstance.Table1, dataSetInstance.Table2, dataSetInstance.Table3);
    }
    

    当我这样做的时候,结果并不太好。dataSetInstance在调用Load方法后只包含一组未填充的表。我希望在第一次调用dataSetInstance.Load之后定期调用dataSetInstance.GetChangesdataSetInstance.AcceptChanges,只获取更改。我做错了吗?

  3. 类型化数据集,其中使用关联的表适配器分别填充表

    using (Table1TableAdapter adapter = new Table1TableAdapter())
    {
        adapter.Fill(dataSetInstance.Table1);
    }
    using (Table2TableAdapter adapter = new Table2TableAdapter())
    {
        adapter.Fill(dataSetInstance.Table2);
    }
    using (Table3TableAdapter adapter = new Table3TableAdapter())
    {
        adapter.Fill(dataSetInstance.Table3);
    }
    

    当然,问题是实际上有3个以上的表,它们加起来可能会产生相当多的重复代码(和维护工作),但真正的问题是,我不会收到任何更改通知,因为我没有使用Load/AcceptChanges方法(根据文档)。

  4. 按日期/时间字段进行行检索:这是我开始做的事情,但在创建行后观察到其他应用程序修改字段后,我停止了。考虑一下:有一行带有事务的时间戳和一个布尔字段,用于指定事务以后是否被取消。如果被取消,另一个应用程序只需返回该行并切换值。时间戳保持不变,我的应用程序永远不会知道这个消息。没有诉讼时效;其他应用程序可以在将来的任何时候更改此字段

顺便说一句,我应该提到的是,这个其他应用程序在数据库中没有实现任何约束,比如外键和主键。我相信我在文档中的某个地方读到,对于行更新事件等,要在类型化的DataTable类上激发,需要某种主键。

一定有办法做到这一点!!!

如何填充类型化数据集、保持其同步以及在数据更改时接收更新

您考虑过SQL Server查询通知吗?这在背后使用了SQL Server Service Broker。

SqlDependency是要查看的C#类。

  • 在Windows应用程序中使用SqlDependency(.NET Framework 2.0示例:应该与更高版本非常相似。)

  • ASP.NET应用程序中的SqlDependency

我会考虑通过实现审计触发器或SQL Server跟踪来在SQL Server级别解决此问题。

触发器–想法是将触发器添加到所有要监视的表中。触发器将捕获所有更改并将数据存储在其他"历史"表中。一旦设置好,您的应用程序所需要做的就是从这些表中读取。

查看此项以了解更多详细信息在SQL Server 中创建审核触发器

跟踪-您可以设置SQL Server跟踪,将所有信息存储在跟踪文件中,然后您的应用程序可以解析跟踪文件并查看发生了什么。

在给定的条件下,似乎没有解决问题的灵丹妙药,但任何事情都比每分钟轮询数据库以获取更改要好。我现在可能要做的是接受Mitch Wheat的建议,并从那里开始工作:

  • 有些表的行极有可能发生更改。例如,最近的一次购买比7天前、6个月前或1年前的购买更有可能被取消——可能永远不会。应用程序只需要监视限制在特定时间范围内的查询。旧的(就创建时间而言)行只会以慢得多的速度刷新,并且不会受到SQL Server查询通知的提示。应用程序将不得不容忍一些过时的数据,以避免不必要地每分钟从数据库中提取整个表
  • 对于没有按时间顺序排列的信息的表,应用程序将不得不接收对重要条件或必须立即采取行动的条件(如WHERE Quantity < 0)的查询通知
  • 对于其余的表格,需要采取一些更聪明的方法。有些表从未更新过,也从未删除过它们的行,但只要其他表的行发生更改,它们就会获得新行。例如:每当Room表中某一行的NumberOfPeople值发生变化时,就会将另一行添加到其中一个表CheckInCheckOut

需要编写更多的代码,但应用程序在运行时可能会减少很多不必要的工作。