1

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

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

这是我到目前为止所做的

  1. LINQ to SQL:据我所知,每次运行查询时,我都会收到一组新数据,但我无法仅接收更改或收到更改通知。
  2. 使用 DataSet.Load 键入 DataSet

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

    当我这样做时,这并没有很好地发挥作用。调用该方法dataSetInstance后仅包含一组未填充的表。Load我希望在第一次致电dataSetInstance.GetChangesdataSetInstance.AcceptChanges定期致电dataSetInstance.Load以获取更改。我做错了吗?

  3. 类型化的 DataSet 使用其关联的表适配器单独填充表

    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 类上触发,需要某种主键。

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

4

3 回答 3

2

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

SqlDependency是要查看的 C# 类。

于 2013-06-30T07:30:38.140 回答
0

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

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

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

于 2013-07-02T08:59:12.923 回答
0

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

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

检查此以获取更多详细信息在 SQL Server 中创建审核触发器

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

于 2013-07-01T11:34:06.930 回答