Detecting Changes with SqlDependency

Giám sát thay đổi của dữ liệu thông qua đối tượng SqlDependency trong .NET (Detecting Changes with SqlDependency)

Đối tượng SqlDependency có thể kết hợp với SqlCommand để giám sát được sự thay đổi của truy vấn so với truy vấn gốc.

Các bước dưới đây hướng dẫn qui trình thực hiện giám sát dữ liệu thay đổi

  1. Khởi tạo một kết nối SqlDependency với máy chủ (CSDL)
  2. Tạo đối tượng SqlConnection và SqlCommand để kết nối với máy chủ và định nghĩa câu truy vấn cần giám sát
  3. Tạo một đối tượng SqlDependency mới và ràng buộc nó với đối tượng SqlCommand
  4. Đăng ký sự kiện cho sự kiện OnChange của đối tượng SqlDependency
  5. Thực hiện câu lệnh bất kỳ (Execute) nào của đối tượng SqlCommand. Bởi vì lệnh này bị ràng buộc với đối tượng thông báo, máy chủ nhận ra rằng nó phải tạo ra một thông báo, và thông tin hàng đợi sẽ trỏ đến hàng đợi phụ thuộc
  6. Kết thúc, dừng giám sát của SqlDependency 

Mã nguồn tham khảo các bước thực hiện

void Initialization()  
{  
    // Create a dependency connection.  
    SqlDependency.Start(connectionString);  
}  
  
void SomeMethod()  
{  
    // Assume connection is an open SqlConnection.  
  
    // Create a new SqlCommand object.  
    using (SqlCommand command=new SqlCommand(  
        "SELECT ShipperID, CompanyName, Phone FROM dbo.Shippers",   
        connection))  
    {  
  
        // Create a dependency and associate it with the SqlCommand.  
        SqlDependency dependency=new SqlDependency(command);  
        // Maintain the refence in a class member.  
  
        // Subscribe to the SqlDependency event.  
        dependency.OnChange+=new  
           OnChangeEventHandler(OnDependencyChange);  
  
        // Execute the command.  
        using (SqlDataReader reader = command.ExecuteReader())  
        {  
            // Process the DataReader.  
        }  
    }  
}  
  
// Handler method  
void OnDependencyChange(object sender,   
   SqlNotificationEventArgs e )  
{  

if (e.Type == SqlNotificationType.Change)
{
NotificationHub nHub = new NotificationHub();
nHub.SendNotifications();
}
  // Handle the event (for example, invalidate this cache entry).  
}  
  
void Termination()  
{  
    // Release the dependency.  
    SqlDependency.Stop(connectionString);  
}
Advertisements

Broadcast real time when data change in database

Hướng dẫn dưới đây về việc broadcase real time khi có thay đổi dữ liệu trong cơ sở dữ liệu (broadcase realtime when data change in database).

Kỹ thuật liên quan để áp dụng bao gồm:

  • SignalR
  • SqlDependency class
  • Sql Service Broker

Các bước cài đặt

  • Thiết lập Sql Service Broker: ON

ALTER DATABASE MyDB SET ENABLE_BROKER;

  • Cài đặt và viết mã SignalR

Mở NuGet Package Manager Console  và gõ lệnh sau

install-package Microsoft.AspNet.SignalR

  • Thiết lập chuỗi kết nối

 

DefaultConnection” connectionString=”data source=SERVER-NAME;database=DATABASENAME;user id =USERID;password=PASSOWRD” providerName=”System.Data.SqlClient” />

 

  • Tạo SignalR Hub class và viết mã nguồn như sau (sử dụng SqlDependency)

[HubName(“notificationHub”)]
public class NotificationHub : Hub
{

Int16 totalNewMessages = 0;
Int16 totalNewCircles = 0;
Int16 totalNewJobs = 0;
Int16 totalNewNotification = 0;

[HubMethodName(“sendNotifications”)]
public void SendNotifications()
{
using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings[“DefaultConnection”].ConnectionString))
{
string query = “SELECT NewMessageCount, NewCircleRequestCount, NewNotificationsCount, NewJobNotificationsCount FROM [dbo].[Modeling_NewMessageNotificationCount] WHERE UserProfileId= 1”;
//(select max(UserProfileId) from [dbo].[Modeling_NewMessageNotificationCount])
connection.Open();
using (SqlCommand command = new SqlCommand(query, connection))
{
try {
command.Notification = null;
DataTable dt = new DataTable();
SqlDependency dependency = new SqlDependency(command);
dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
if (connection.State == ConnectionState.Closed)
connection.Open();
var reader = command.ExecuteReader();
dt.Load(reader);
if (dt.Rows.Count > 0)
{
totalNewMessages = Int16.Parse(dt.Rows[0][“NewMessageCount”].ToString());
totalNewCircles = Int16.Parse(dt.Rows[0][“NewCircleRequestCount”].ToString());
totalNewJobs = Int16.Parse(dt.Rows[0][“NewJobNotificationsCount”].ToString());
totalNewNotification = Int16.Parse(dt.Rows[0][“NewNotificationsCount”].ToString());
}
connection.Close();
}
catch(Exception ex)
{
throw;
}
}
}

//Call function on Client
IHubContext context = GlobalHost.ConnectionManager.GetHubContext();
context.Clients.All.RecieveNotification(totalNewMessages, totalNewCircles, totalNewJobs, totalNewNotification);
}
private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
{
if (e.Type == SqlNotificationType.Change)
{
NotificationHub nHub = new NotificationHub();
nHub.SendNotifications();
}
}
}

  • Mapping SignalR trong Startup.cs class
[assembly: OwinStartup("Testing", typeof(MyStartup))]
 public class MyStartup
 {
 public void Configuration(IAppBuilder app)
 {
 app.MapSignalR(); 
 }
 }
  • Start and Stop SqlDependency
Global.asax 
void Application_Start(object sender, EventArgs e)  
    { 
        // Code that runs on application startup 
        System.Data.SqlClient.SqlDependency.Start(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString); 
    } 
     
    void Application_End(object sender, EventArgs e)  
    { 
        //  Code that runs on application shutdown 
        System.Data.SqlClient.SqlDependency.Stop(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString); 
 
    }
  • Client code
 
    New Notifications 
    "Scripts/jquery-1.6.4.min.js"> 
    "Scripts/jquery.signalR-2.0.2.min.js">         
    "signalr/hubs"> 
    "text/javascript"> 
        $(function () {             
            // Declare a proxy to reference the hub. 
            var notifications = $.connection.notificationHub; 
            debugger; 
            // Create a function that the hub can call to broadcast messages. 
            notifications.client.recieveNotification = function (totalNewMessages, totalNewCircles, totalNewJobs, totalNewNotifications) { 
                // Add the message to the page.                 
                $('#spanNewMessages').text(totalNewMessages); 
                $('#spanNewCircles').text(totalNewCircles); 
                $('#spanNewJobNotifications').text(totalNewJobs); 
                $('#spanNewNotifications').text(totalNewNotifications); 
            }; 
            // Start the connection. 
            $.connection.hub.start().done(function () { 
                notifications.server.sendNotifications(); 
            }).fail(function (e) { 
                alert(e); 
            }); 
            //$.connection.hub.start();             
        }); 
     
  

Broadcast Realtime SQL data using SignalR


You have “spanNewMessages”>0 New Message Notification.
You have “spanNewCircles”>0 New Circles Notification.
You have “spanNewJobNotifications”>0 New Job Notification.
You have “spanNewNotifications”>0 New Notification.

 

Source: Microsoft