Inloggen
 
 
 
 
    
How to use class SqlCacheDependency in code
Location: BlogsHugo de Vreugd - Developer    
Posted by: Hugo Vreugd, de 4-2-2008 10:39
This article explains the steps to use class SqlCacheDependency in ASP.Net 2.0 and notification services in SQL Server 2005 in code.

Intro:
Caching can improve your websites performance. This article describes how to use a specific variant of caching: using the SqlCacheDependency class to cache objects that depend on a SQL Server 2005 table.
All example code uses the Northwind example database.

Prepare the database:
In order to use the SqlCacheDependency class, the database has to be configured to use the service broker (notification services).
First check if the service broker is enabled:

         SELECT is_broker_enabled FROM sys.databases WHERE name = 'Northwind'

When this query returns 1 the broker is enabled and we are done with SQL Server.
If not, enable the broker by using this alter table statement:

         ALTER DATABASE Northwind SET ENABLE_BROKER

Two problems I have encountered using this statement:
1. It keeps running.
2. It returns error 9772: The Service Broker in database 'Northwind' cannot be enabled because there is already an enabled Service Broker with the same ID.

This problems can be solved by using resp.:
1. Change the statement to ALTER DATABASE Northwind SET ENABLE_BROKER WITH ROLLBACK IMMEDIATE
2. First execute statement ALTER DATABASE Northwind SET NEW_BROKER and then again try to enable the broker.

Prepare the web application:
In the Global.asax file add the following statement to the Application_Start subroutine:
   System.Data.SqlClient.SqlDependency.Start("Data Source=localhost;Initial Catalog=Northwind;Integrated Security=True")
And allmost the same statement in Application_Stop:
System.Data.SqlClient.SqlDependency.Stop("Data Source=localhost;Initial Catalog=Northwind;Integrated Security=True")

Using the Cache:
The big advantage of using class SqlCacheDependency is you don't need to poll to check for changes in the database. SqlCacheDependency and SQL Server will take care of that part.
In this example we want to cache customer data of customers located in the USA. Whenever someone in someway (using another app or executing an UPDATE statement in SQL) changes something in a customer row with country equal to USA, then the cached object gets cleared, and you have to get the data again.
This example function returns a datatable of all USA customers:

    Private Function GetCustomers() As DataTable

        Dim dt As DataTable = DirectCast(HttpContext.Current.Cache.Get("cust"), DataTable)

        If dt Is Nothing Then

            Dim cn As New SqlConnection("Data Source=localhost;Initial Catalog=Northwind;Integrated Security=True")
            Dim cm As New SqlCommand("SELECT CustomerID, CompanyName, ContactName FROM dbo.Customers WHERE Country = 'USA'", cn)
            Dim dependency As SqlCacheDependency = New SqlCacheDependency(cm)
            Dim da As New SqlDataAdapter(cm)

            dt = New DataTable()
            da.Fill(dt)

            HttpContext.Current.Cache.Insert("cust", dt, dependency)

        End If

        Return dt

    End Function

Limitations:
Some limitations exist regarding the SQL statement. The most important one is to always use the table owner prefix before the table, like in the example code: dbo. Another limitation is that you are not allowed to use SELECT *.
Be aware of more limitations of your SQL.

Another problem that may occur when updating the contents of the watched table whil "SET ANSI_WARNINGS OFF" is used, is error 1934: "UPDATE failed because the following SET options have incorrect settings: 'ANSI_WARNINGS'. Verify that SET options are correct for use with indexed views and/or indexes on computed columns and/or query notifications and/or xml data type methods.".
So "SET ANSI_WARNINGS OFF" is not allowed when changing something in table Customers.

 


 

Copyright ©2008 Hugo de Vreugd
Permalink |  Trackback

Comments (6)  
Re: How to use class SqlCacheDependency in code    By Angelina on 4-8-2008 14:00
The given blog is clear and fine. I have a query regarding this. Can this sqldependency caching be done even for update statement or only for forward only? If so, How?

Betr: How to use class SqlCacheDependency in code    By Hugo on 18-8-2008 6:54
SqlDependency can only be used with a sql select statement. The reason is that this statement defines the set of rows and columns SQL Server will be monitoring. Any change to this set by an update, delete or insert will clear the cache.

Re: How to use class SqlCacheDependency in code    By RT on 8-9-2008 10:58
THANK YOU
i begin with .dotnet and then sqldependency
i want to how to define set a option in my querry :
select NumeroTitre,NumeroFacture from dbo.Titre

Betr: How to use class SqlCacheDependency in code    By Hugo on 8-9-2008 11:13
@RT:

Do you mean parameterizing your query? If so, you have to change the query in the example like this:
Dim cm As New SqlCommand("SELECT CustomerID, CompanyName, ContactName FROM dbo.Customers WHERE Country = @Country", cn)
cm.Parameters.AddWithValue("@Country", "USA")

If, on the other hand, you want in this example a cache object per country, you might use something like:
Private Function GetCustomers(ByVal Country As String) As DataTable

Dim dt As DataTable = DirectCast(HttpContext.Current.Cache.Get("custOf" & Country), DataTable)

If dt Is Nothing Then

Dim cn As New SqlConnection("Data Source=localhost;Initial Catalog=Northwind;Integrated Security=True")
Dim cm As New SqlCommand("SELECT CustomerID, CompanyName, ContactName FROM dbo.Customers WHERE Country = @Country", cn)
cm.Parameters.AddWithValue("@Country", Country)
Dim dependency As SqlCacheDependency = New SqlCacheDependency(cm)
Dim da As New SqlDataAdapter(cm)

dt = New DataTable()
da.Fill(dt)

HttpContext.Current.Cache.Insert("custOf" & Country, dt, dependency)

End If

Return dt

End Function

Regards, Hugo.

Re: How to use class SqlCacheDependency in code    By Gonzalo on 3-11-2008 20:40
Hi, i have an issue regarding the sqlcachedependency object. When i insert the element in the cache, the "haschanged" property of the sqlcachedependency goes to TRUE every time, so it always erase the item from the cache after the insert. ¿¿Do you know why this is hapenning??
Regards,
Gonzalo.

Re: How to use class SqlCacheDependency in code    By Tim on 8-12-2008 19:33
First, if the "ENABLE BROKER" statement is hanging, it's because you need exclusive access to the database before it can be enabled. This means absolutely nothing can be connected to it. So when you run it, it needs to look like this:

USE [master]
GO
ALTER DATABASE [Northwind] SET ENABLE_BROKER
GO

As far as anyone having issues with the "haschanged" property immediately returning true, it's probably because your queries are not written to the standards that the Broker needs in order to detect changes. For example, you cannot use JOINS and you must specify the full table names (ex. Select ... FROM dbo.MyTable - not just "Select ... FROM MyTable"). Also, you must explicitly list the columns, no "Select *" allowed!

  
 
Weblogs
    
Archief
    
Zoeken
    
 
 
 
 
Copyright 2006-2009 by Arcencus
Privacy Statement | Terms Of Use