Notifications SQL Server CE通知服务

Notifications SQL Server CE通知服务,notifications,sql-server-ce,Notifications,Sql Server Ce,我已经找了一段时间,但没有找到任何真正的答案。我正在尝试构建一个使用SQLServerCE实现可移植性的应用程序,我需要在更新数据库时触发一个事件。是否还有其他方法可以做到这一点,比如使用SQL Server CE的通知服务 感谢这是进行轻量级轮询的类的开始,需要监视的表具有标识列: using System; using System.Collections.Generic; using System.Text; using System.Data.SqlServerCe; /// <

我已经找了一段时间,但没有找到任何真正的答案。我正在尝试构建一个使用SQLServerCE实现可移植性的应用程序,我需要在更新数据库时触发一个事件。是否还有其他方法可以做到这一点,比如使用SQL Server CE的通知服务


感谢

这是进行轻量级轮询的类的开始,需要监视的表具有标识列:

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
}
使用系统;
使用System.Collections.Generic;
使用系统文本;
使用System.Data.SqlServerCe;
/// 
///Sql紧凑查询通知类
/// 
公共密封类SqlCeDependency:IDisposable
{
private System.Timers.Timer Timer=新的System.Timers.Timer();
私有Int64 lastUsedIdentity=Int64.MinValue;
私有Int64 currentIdentity=Int64.MinValue;
专用SQLC连接连接器;
私有字符串tabletwatch;
/// 
///在基础表更改时发生。
///仅适用于插入件的初始支撑
/// 
公共事件事件处理程序OnChange;
/// 
///初始化类的新实例。
/// 
///这张桌子要看。
///连接字符串。
公共SqlCeDependency(字符串表观察、字符串连接字符串)
{
this.tableToWatch=tableToWatch;
StartTimer(20,连接字符串);
}
/// 
///初始化类的新实例。
/// 
///这张桌子要看。
///SQL压缩连接字符串。
///时间间隔以秒为单位。
公共SqlCeDependency(字符串表观察、字符串连接字符串、int间隔)
{
this.tableToWatch=tableToWatch;
StartTimer(间隔、连接字符串);
}
私有void CheckDependency(字符串tabletWatch)
{
使用(SqlCeCommand cmd=conn.CreateCommand())
{
cmd.CommandText=string.Format(“从INFORMATION_SCHEMA.COLUMNS中选择AUTOINC_NEXT,其中TABLE_NAME='{0}'和AUTOINC_NEXT不为空”,tableToWatch);
if(conn.State!=System.Data.ConnectionState.Open)
{
conn.Open();
}
object obj=cmd.ExecuteScalar();
if(obj==null)
{
抛出新的NotSupportedException(“监视表上需要标识列”);
}
其他的
{
lastUsedIdentity=(Int64)对象;
}
if(currentIdentity==Int64.MinValue)
{
currentIdentity=lastUsedIdentity;
}                
}
}
私有void StartTimer(整数间隔,字符串连接字符串)
{
定时器间隔=间隔*1000;
timer.AutoReset=true;
timer.Enabled=true;
timer.appeated+=新系统.Timers.ElapsedEventHandler(timer_appeated);
conn=新的SqlCeConnection(connectionString);
conn.Open();
}
无效计时器(对象发送器,System.Timers.ElapseDevenTargets e)
{
检查相关性(tableToWatch);
if(lastUsedIdentity!=currentIdentity)
{
currentIdentity=lastUsedIdentity;
if(OnChange!=null)
{
OnChange(this,EventArgs.Empty);
}
}
}
公共bool HasChanges{get;set;}
#区域IDisposable成员
公共空间处置()
{
如果(conn!=null)
{
conn.Dispose();
}
}
#端区
}

由于SQL Server CE实际上不是一台服务器(尽管名称不同),而是应用程序中的一个“嵌入式”数据库,因此恐怕没有提供此类服务。您必须定期轮询您的数据库表以检测更改,然后对发生的更改做出反应……我不久前实现了一个非常“轻量级”的轮询机制,如果您感兴趣,请告诉我,我将尝试挖掘它。嗨,ErikEJ,那太棒了!