10

我有一个表和一个等待新插入的 SqlDependency。

OnChange 根据需要触发,但我不明白是否可以获得导致数据库更改的行。

SqlDependency sql命令:

SqlCommand cmd = new SqlCommand("SELECT id FROM dbo.DataRequests", m_sqlConn);

OnChange 代码:

private void OnChange(object sender, SqlNotificationEventArgs e)
{
    SqlDependency dependency = sender as SqlDependency;

    dependency.OnChange -= OnChange;

    Console.WriteLine("Info:   " + e.Info.ToString());
    Console.WriteLine("Source: " + e.Source.ToString());
    Console.WriteLine("Type:   " + e.Type.ToString());


    Console.WriteLine(DateTime.Now);

    GetMessages();

}
4

7 回答 7

9

看看这个组件: SqlTableDependency

对于 SQL Server 数据库表上的每一次更改,C# 代码都会收到一个事件,其中包含更改的记录列表。

于 2015-08-10T07:24:44.903 回答
7

没有关于导致依赖项被触发的行的信息。

我想作为一种解决方法,您总是可以在记录上加上时间戳并跟踪事件上次触发的时间。

于 2013-02-14T15:04:15.830 回答
2

根据这篇文章,你不能:http ://social.msdn.microsoft.com/Forums/en-US/sqlservicebroker/thread/07234067-73e1-4db5-a4e6-0f9f0bae22ae/

您只能通过使用属性来缩小通知的原因

提供的SqlNotificationEventArgs

于 2013-02-14T14:58:31.667 回答
2

在这里找到一个非常巧妙的解决方案

于 2017-03-15T15:02:25.377 回答
0

只需使用跨平台的 .NET 3.5 兼容和开源SqlDependencyEx。它使用数据库触发器和本机 Service Broker 通知来接收有关表更改的事件。这是一个使用示例:

int changesReceived = 0;
using (SqlDependencyEx sqlDependency = new SqlDependencyEx(
          TEST_CONNECTION_STRING, TEST_DATABASE_NAME, TEST_TABLE_NAME)) 
{
    sqlDependency.TableChanged += (o, e) => changesReceived++;
    sqlDependency.Start();

    // Make table changes.
    MakeTableInsertDeleteChanges(changesCount);

    // Wait a little bit to receive all changes.
    Thread.Sleep(1000);
}

Assert.AreEqual(changesCount, changesReceived);

您可以获得更改通知以及更改的信息。请点击链接了解详情。

于 2019-03-22T23:09:54.150 回答
-1

我希望这可以帮助你:

     string commandString = string.Format("SELECT [Id] FROM [dbo].[Tech]");
     command = new SqlCommand(commandString, connection);

    private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
    {
        SqlDependency dependency = (SqlDependency)sender;
        dependency.OnChange -= dependency_OnChange;

        this.Dispatcher.Invoke((System.Action)(() =>
        {

            if (e.Info.ToString().ToLower().Trim() == "insert")
            {
                GetData();
                int NewTechID = TechIDs.Last();
            }

        }));
    }

    private void GetData()
    {
        command.Notification = null;
        SqlDependency dependency = new SqlDependency(command);
        dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);

        command.Connection.Open();
        using (SqlDataReader reader = command.ExecuteReader())
        {
            while (reader.Read())
            {
                TechIDs.add(int.Parse(reader.GetValue(0).ToString()));
            }
            reader.Close();
        }
        command.Connection.Close();
    }
于 2013-02-18T07:36:40.693 回答
-1

您可以使用临时表。首先,您需要创建一个临时表,其中包含您需要继续调查的所有字段。就像是:

CREATE TABLE ##TempTab(
    [field1] [varchar](50) NULL,
    [field2] [varchar](50) NULL
}

请注意,在创建程序退出后,在外部 cose 中创建的表会自动删除,因此您无需在 formClosing 上删除它...现在,在设置 sqlDepency 内容后,您必须填写临时表,这是一些就像开始场景的快照。然后,每次触发 onChange 事件时,您只需将临时表与更新的情况进行比较。它可能是这样的:

    select * from ##temptable left outer join mytable
ON ##temptable.field1=myTable.field1 AND ##temptable.field2=myTable.field2
WHERE myTable.field2 is null

这将为您提供刚刚删除的所有行(或使用旧值更改)。另一方面:

select * from mytable left outer join ##temptable
    ON ##temptable.field1=myTable.field1 AND ##temptable.field2=myTable.field2
    WHERE ##temptable.field2 is null

将为您提供刚刚添加的所有行(或使用新值更改)。在此比较之后,您只需要使用新值更新您的临时表(更快的方法是删除所有内容并插入所有值)当然,如果您的程序将由不同用户同时运行,您需要处理临时表中的用户 ID .

于 2013-10-01T10:25:44.540 回答