zoukankan      html  css  js  c++  java
  • sqlDependency

    sqlDependency提供了这样一种能力:当被监测的数据库中的数据发生变化时,SqlDependency会自动触发OnChange事件来通知应用程序,从而达到让系统自动更新数据(或缓存)的目的.

    快速上手可参见园友的下列文章

    http://www.cnblogs.com/xrinehart/archive/2006/07/27/461106.html .NET 2.0 SqlDependency快速上手指南
    http://www.cnblogs.com/gesenkof99/archive/2008/12/19/1358584.html 采用SQLServer2005 Broker和SqlDependency类来提供数据更改通知(原创)

    例子:

     代码:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Data.SqlClient;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication4
    {
        public partial class Form1 : Form
        {
            static DataSet ds = new DataSet();
            static  string connStr = "Data Source = (local)\SQLEXPRESS; Initial Catalog = northwind; Persist Security Info = True;User ID=sa;Password=6617saSA";
            // 必须有[dbo]. , 否则 dependency.OnChange 不断出现
            static string sql = "SELECT CustomerID  编号,CompanyName  ,ContactName ,ContactTitle  ,Address ,City  FROM [dbo].[Customers] ;";
            static  SqlDataAdapter sda ;
            static  BindingSource bindingsource1 ;
            public Form1()
            {
                InitializeComponent();
                System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                dataGridView1.AllowUserToAddRows = false; //去掉DataGridView的最后一个空行
                bindingsource1 = new BindingSource();
                sda = new SqlDataAdapter(sql, connStr);
                sda.Fill(ds, "Customers");    
                bindingsource1.DataSource = ds;
                bindingsource1.DataMember = ds.Tables["Customers"].TableName;
    
                // 设置主键
                //在同一个 DataTable 上多次使用 Fill 方法。如果主键存在,则传入行会与已有的匹配行合并。如果主键不存在,则传入行会追加到 DataTable 中。
                DataColumn[] PrimaryKeyColumns = new DataColumn[1];
                PrimaryKeyColumns[0] = ds.Tables["Customers"].Columns["编号"];
                ds.Tables["Customers"].PrimaryKey = PrimaryKeyColumns;
    
                bindingNavigator1.BindingSource = bindingsource1;
                dataGridView1.DataSource = bindingsource1;
    
                //textBox_ID.DataBindings.Add("text", bs, "编号",false, DataSourceUpdateMode.OnPropertyChanged);
                //textBox_name.DataBindings.Add("text", bs, "CompanyName", false, DataSourceUpdateMode.OnPropertyChanged);
                textBox_ID.DataBindings.Add("text", bindingsource1, "编号");
                textBox_name.DataBindings.Add("text", bindingsource1, "CompanyName");
    
                textBox_ContactName.DataBindings.Add("text", bindingsource1, "ContactName");
                textBox_ContactTitle.DataBindings.Add("text", bindingsource1, "ContactTitle");
                textBox_Address.DataBindings.Add("text", bindingsource1, "Address");
                textBox_City.DataBindings.Add("text", bindingsource1, "City");
    
                SqlDependency.Start(connStr);//传入连接字符串,启动基于数据库的监听
                RegisterOnChangeEvent();
            }
    
            private void toolStripButton_save_Click(object sender, EventArgs e)
            {
                //该语句使修改cell内容后直接保存有效,否则需要移动到其它CELL再保存才有效
                dataGridView1.CurrentCell = null; 
                //将控制修改内容更新到DataSet基础数据,如果没有EndEdit() , ds.GetChanges() == null永远成立
                ((BindingSource)dataGridView1.DataSource).EndEdit();
                if (ds.GetChanges() != null)
                {
                    //没有下一条会出现错误:当传递具有新行的 DataRow 集合时,Update 要求有效的 InsertCommand
                    SqlCommandBuilder sb1 = new SqlCommandBuilder(sda);
                    try
                    {
                        sda.Update(ds.Tables["Customers"]);//更新数据库
                        ds.AcceptChanges();
                    }
                    catch(Exception ee)
                    {
                        MessageBox.Show(ee.Message);
                    } 
                }
            }
    
            private void RegisterOnChangeEvent()
            {          
                using (SqlConnection connection = new SqlConnection(connStr))
                {
                    //依赖是基于某一张表的,而且查询语句只能是简单查询语句,不能带top或*,同时必须指定所有者,即类似[dbo].[]
                    using (SqlCommand command = new SqlCommand(sql, connection))
                    {
                        command.CommandType = CommandType.Text;
                        connection.Open();
                        SqlDependency dependency = new SqlDependency(command);
                        dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
    
                        // Execute the command. 必须有
                        using (SqlDataReader reader = command.ExecuteReader())
                        {
                        }
    
                    }
                }
            }
    
            private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
            {
                sda.Fill(ds, "Customers");
                RegisterOnChangeEvent();
            }
        }
    }

    3.测试运行

    运行该控制台程序后,会输出[Messages]表的所有数据,这时不要关闭控制台程序,直接在Sql2005的管理器里对[Messages]表的数据做些修改(比如新增/删除等),再看一下控制台,会发现自动重新输出了新的数据.


    注意:如果在web应用中,因为页面必须通过浏览器请求才能激活服务端的处理,所以页面一旦处理完成并显示到浏览器后,放着不动的情况下,OnChange事件始终是得不到触发的.

    最后再推荐一篇园子里高人的文章:
    http://www.cnblogs.com/artech/archive/2008/08/11/1265055.html 是结合Enterprise Library的缓存应用程序块与SqlDependency的综合应用,写得很不错,强烈推荐想使用缓存的朋友看看.

  • 相关阅读:
    Django REST framework
    Docker学习11-sonarqube+jenkins持续集成代码审计(下)
    Docker学习10-sonarqube+jenkins持续集成代码审计(上)
    jmeter-4-linux下环境搭建 jmeter+ant+docker-jenkins,持续集成测试完成
    jmeter-3-linux下环境搭建jmeter+ant
    jmeter-2-ant+jenkins持续集成测试
    jmeter-1-apache ant-集成测试
    python-50-pip加速与pip包虚拟环境管理
    git-基本操作
    创建 PHP Composer 包并使用的操作指南
  • 原文地址:https://www.cnblogs.com/wfy680/p/14800960.html
Copyright © 2011-2022 走看看