2013-05-05 52 views
13

Tôi cần triển khai SqlCacheDependency cho một bảng sẽ phụ thuộc vào truy vấn này: SELECT Nickname FROM dbo.[User].Làm thế nào để sử dụng SqlCacheDependency?

Tôi đã tạo ra một phương pháp cho mục đích này:

private IEnumerable<string> GetNicknamesFromCache() 
    { 
     const String cacheValueName = "Nicknames"; 

     var result = HttpRuntime.Cache.Get(cacheValueName) as List<String>; 
     if (result == null) 
     { 
      result = _repository.GetAllNicknames(); 

      var connectionString = ConfigurationManager.ConnectionStrings["RepositoryContext"].ConnectionString; 
      var sqlConnection = new SqlConnection(connectionString); 
      var sqlCommand = new SqlCommand("SELECT Nickname FROM dbo.[User]", sqlConnection); 
      var sqlDependency = new SqlCacheDependency(sqlCommand); 

      HttpRuntime.Cache.Insert(cacheValueName, result, sqlDependency); 
     } 

     return result; 
    } 

Nhưng khi tôi chạy ứng dụng của tôi nó không hoạt động. Tôi đã kiểm tra danh sách người đăng ký (sys.dm_qn_subscriptions bảng) và không có hồ sơ nào.

tôi điều tra nhiều thời gian và đã cố gắng giải pháp khác nhau nhưng họ không làm việc cho tôi:

  • sử dụng kết nối đáng tin cậy và thiết lập một số điều khoản cho vai trò công cộng:

    GRANT CREATE PROCEDURE TO public
    GRANT CREATE QUEUE TO public
    GRANT CREATE SERVICE TO public
    GRANT SUBSCRIBE QUERY NOTIFICATIONS TO public
    GRANT SELECT ON OBJECT::dbo.[User] TO public
    GRANT RECEIVE ON QueryNotificationErrorsQueue TO public

  • sử dụng 'sa' đăng nhập để kết nối

  • aspnet_regsql.exe sử dụng (aspnet_regsql.exe -S localhost -E -ed -d TestTable -et -t User)
  • thêm cấu hình để system.webServer trong web.config:

    <caching>
    <sqlCacheDependency enabled="true">
    <databases>
    <add name="Tmpl" pollTime="5000" connectionStringName="RepositoryContext"/>
    </databases>
    </sqlCacheDependency>
    </caching>

  • đặt SqlDependency.Start() vào sự kiện Global.asax Application_Start

  • chạy ở trường hợp khác nhau của máy chủ sql (SQL Server 2008 Express, SQL Máy chủ 2008)

Nhưng nó không giúp được gì. Nó vẫn không hoạt động.

Làm cách nào để nó hoạt động?

Trả lời

18

Tôi đã tìm thấy giải pháp.

Tại kiểm tra đầu tiên cho dù dịch vụ môi giới được kích hoạt cho bảng của bạn và kích hoạt nó nếu cần thiết:

SELECT name, is_broker_enabled FROM sys.databases WHERE name = '<databaseName>' 

ALTER DATABASE <databaseName> SET enable_broker WITH ROLLBACK IMMEDIATE 

Tiếp theo tạo trong SQL Server vai trò mới sql_dependency_role, cấp quyền cho nó và cấp vai trò cho người sử dụng:

EXEC sp_addrole 'sql_dependency_role' 

GRANT CREATE PROCEDURE to sql_dependency_role 
GRANT CREATE QUEUE to sql_dependency_role 
GRANT CREATE SERVICE to sql_dependency_role 
GRANT REFERENCES on CONTRACT::[http://schemas.microsoft.com/SQL/Notifications/PostQueryNotification] to sql_dependency_role 
GRANT VIEW DEFINITION TO sql_dependency_role 
GRANT SELECT to sql_dependency_role 
GRANT SUBSCRIBE QUERY NOTIFICATIONS TO sql_dependency_role 
GRANT RECEIVE ON QueryNotificationErrorsQueue TO sql_dependency_role 

EXEC sp_addrolemember 'sql_dependency_role', '<userName>' 

Sau đó, thêm mã C# để làm việc với SqlCacheDependency hoặc SqlDependency (chủ yếu là theo cùng một cách).

Tôi đã thay đổi phương pháp của tôi và bây giờ nó trông như thế này:

private IEnumerable<string> GetNicknamesFromCache() 
    { 
     const String cacheValueName = "Nicknames"; 

     var result = HttpRuntime.Cache.Get(cacheValueName) as List<String>; 
     if (result == null) 
     { 
      result = _repository.GetAllNicknames(); 

      using (var connection = new SqlConnection(_config.ConnectionString)) 
      { 
       connection.Open(); 

       SqlDependency.Start(_config.ConnectionString); 
       var command = new SqlCommand("SELECT Nickname FROM dbo.[User]", connection); 
       var dependency = new SqlCacheDependency(command); 
       HttpRuntime.Cache.Insert(cacheValueName, result, dependency); 

       command.ExecuteNonQuery(); 
      } 
     } 

     return result; 
    } 

Bây giờ nó hoạt động tốt.

Đừng quên gọi phương thức SqlDependency.Start trước khi tạo SqlCacheDependency hoặc SqlDependency và thực hiện lệnh của bạn ở cuối.

+0

Bạn có cần giữ kết nối mở khi bạn đã thực hiện ở đây hoặc bạn có thể đóng/hủy nó không? –

+0

Trả lời câu hỏi của tôi ở trên - nó là cần thiết để giữ cho kết nối này mở để các nhà môi giới dịch vụ có thể gửi các thông báo đó. Điều này khiến thiết kế này khó hơn một chút nếu bạn có nhiều mục trong bộ nhớ cache cần được làm mới. –

Các vấn đề liên quan