|
Dieser Artikel bezieht sich auf den MSDN Artikel "Ein SQL-SiteMapProvider für SQL Server und ASP.NET 2.0".
Wir haben den Code des Providers für das Menü unserer Hompage verwendet, mussten aber leider einige Fehler feststellen bzw. haben einige Verbesserungen hinzugefügt um das Ganze zum Laufen zu bringen.
SqlCacheDependency
Das erste Problem trat mit der Verwendung der SqlCacheDependency über das Command-Objekt auf. Um das Feature der Abhänhängigkeit vom Command-Objekt zu nutzen, muss auf der verwendeten Datenbank der Service Broker aktiviert sein. Die kann man mit dem Datenbankbefehl
Alter Database DBName Set Enable_Broker;
erreichen.
Danach funktionierte die erste Abfrage, allerdings wurde bei einer Änderung der Daten in der Datenbank kein Event ausgelöst und die Abfrage nie neu durchgeführt.
SQL Abfrage-Syntax
Nach einigem Suchen und dem studieren der Hilfe zur SqlCacheDependency-Klasse fandenwir heraus, dass die Benachrichtigungen nur bei "einfachen Abfragen" von Tabellen funktionieren, nicht aber bei Stored Procedures wie im ursprünglichen Code. Wir stellten den Aufruf von "proc_GetSiteMap" auf etwas wie "Select * from SiteMapData" um, um der Spezifikation in der Hilfe zu entsprechen.
Leider stellte sich immer noch nicht der gewünschte Erfolg ein.
Datenbank Kompatibilitätslevel
Nach einigem Suchen in diversen Foren war die Lösung gefunden: da die Benachrichtigungen ein neues Feature von SQL Server 2005 sind, muss der Kompatibilitätsgrad der verwendeten Datenbank auf "SQL Server 2005 (90)" gestellt werden, dann läuft alles rund.
Datenbank Schema
Die in unserer Variante verwendete Tabelle hat folgendes Schema:
CREATE TABLE [dbo].[WebContent2]( [ID] [int] NOT NULL, [Parent] [int] NOT NULL, [Title] [nvarchar](70) NOT NULL, [Url] [nvarchar](70) NULL, [Description] [nvarchar](300) NULL, [SortOrder] [int] NOT NULL, [ShowMenu] [bit] NOT NULL, [ShowSitemap] [bit] NOT NULL, [ShowNavBar] [bit] NOT NULL, [IsKursNode] [bit] NOT NULL ) ON [PRIMARY]
Code
Nachfolgend unsere Modifikation des ursprünglichen Codes in der Methode BuildSiteMap():
public override SiteMapNode BuildSiteMap() { lock (_lock) { // Return immediately if this method has been called before if (_root != null) { return _root; } // Query the database for site map nodes SqlConnection connection = new SqlConnection(_connect); try { SqlCommand command = new SqlCommand("Select ID, Parent, Title, Url, Description, " +"'' as Roles From dbo.WebContent2 Where ShowMenu = 1 Order By SortOrder Asc", connection); command.CommandType = CommandType.Text;
// Create a SQL cache dependency if requested SqlCacheDependency dependency = null; if (_2005dependency) dependency = new SqlCacheDependency(command); else if (!String.IsNullOrEmpty(_database) && !string.IsNullOrEmpty(_table)) dependency = new SqlCacheDependency(_database, _table);
connection.Open(); SqlDataReader reader = command.ExecuteReader();
_indexID = reader.GetOrdinal("ID"); _indexUrl = reader.GetOrdinal("Url"); _indexTitle = reader.GetOrdinal("Title"); _indexDesc = reader.GetOrdinal("Description"); _indexRoles = reader.GetOrdinal("Roles"); _indexParent = reader.GetOrdinal("Parent");
if (reader.Read()) { // Create the root SiteMapNode and add it to the site map _root = CreateSiteMapNodeFromDataReader(reader); AddNode(_root, null);
// Build a tree of SiteMapNodes underneath the root node while (reader.Read()) { // Create another site map node and add it to the site map SiteMapNode node = CreateSiteMapNodeFromDataReader(reader); AddNode(node, GetParentNodeFromDataReader(reader)); }
// Use the SQL cache dependency if (dependency != null) { HttpRuntime.Cache.Insert(_cacheDependencyName, new object(), dependency, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable, new CacheItemRemovedCallback(OnSiteMapChanged)); } } } finally { connection.Close(); } // Return the root SiteMapNode return _root; } } |