0

我一直在寻找一段时间,但没有找到任何真正的答案。我正在尝试构建一个使用 SQL Server CE 实现可移植性的应用程序,并且我需要在更新数据库时触发一个事件。有没有办法做到这一点,比如使用 SQL Server CE 的通知服务?

谢谢

4

1 回答 1

0

这是进行轻量级轮询的类的开始,需要被监视的表有一个 IDENTITY 列:

using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlServerCe;

/// <summary>
/// Sql Compact query notification class
/// </summary>
public sealed class SqlCeDependency : IDisposable 
{
    private System.Timers.Timer timer = new System.Timers.Timer();

    private Int64 lastUsedIdentity = Int64.MinValue;
    private Int64 currentIdentity = Int64.MinValue;

    private SqlCeConnection conn;

    private string tableToWatch;

    /// <summary>
    /// Occurs when the underlying table changes.
    /// Initial support only for Inserts
    /// </summary>
    public event EventHandler OnChange;

    /// <summary>
    /// Initializes a new instance of the <see cref="SqlCeDependency"/> class.
    /// </summary>
    /// <param name="tableToWatch">The table to watch.</param>
    /// <param name="connectionString">The connection string.</param>
    public SqlCeDependency(string tableToWatch, string connectionString)
    {
        this.tableToWatch = tableToWatch;
        StartTimer(20, connectionString);
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="SqlCeDependency"/> class.
    /// </summary>
    /// <param name="tableToWatch">The table to watch.</param>
    /// <param name="connectionString">The SQL Compact connection string.</param>
    /// <param name="interval">The interval in seconds.</param>
    public SqlCeDependency(string tableToWatch, string connectionString, int interval)
    {
        this.tableToWatch = tableToWatch;            
        StartTimer(interval, connectionString);
    }

    private void CheckDependency(string tableToWatch)
    {
        using (SqlCeCommand cmd = conn.CreateCommand())
        {
            cmd.CommandText = string.Format("SELECT AUTOINC_NEXT FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '{0}' AND AUTOINC_NEXT IS NOT NULL", tableToWatch);

            if (conn.State != System.Data.ConnectionState.Open)
            {
                conn.Open();
            }
            object obj = cmd.ExecuteScalar();
            if (obj == null)
            {
                throw new NotSupportedException("IDENTITY column is required on watched table");
            }
            else
            {
                lastUsedIdentity = (Int64)obj;
            }
            if (currentIdentity == Int64.MinValue)
            {
                currentIdentity = lastUsedIdentity;
            }                
        }
    }

    private void StartTimer(int interval, string connectionString)
    {
        timer.Interval = interval * 1000;
        timer.AutoReset = true;
        timer.Enabled = true;
        timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
        conn = new SqlCeConnection(connectionString);
        conn.Open();
    }

    void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        CheckDependency(tableToWatch);
        if (lastUsedIdentity != currentIdentity)
        {
            currentIdentity = lastUsedIdentity;
            if (OnChange != null)
            {
                OnChange(this, EventArgs.Empty);
            }
        }
    }

    public bool HasChanges { get; set; }


    #region IDisposable Members

    public void Dispose()
    {
        if (conn != null)
        {
            conn.Dispose();
        }
    }

    #endregion
}
于 2013-05-26T15:12:47.207 回答