使用 SQL 緩存依賴項(xiàng)C#_第1頁(yè)
使用 SQL 緩存依賴項(xiàng)C#_第2頁(yè)
使用 SQL 緩存依賴項(xiàng)C#_第3頁(yè)
使用 SQL 緩存依賴項(xiàng)C#_第4頁(yè)
使用 SQL 緩存依賴項(xiàng)C#_第5頁(yè)
已閱讀5頁(yè),還剩22頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

本文檔是VisualC#教程(切換到VisualBasic教程)最簡(jiǎn)單的緩存策略就是使緩存數(shù)據(jù)在一個(gè)指定的時(shí)間周期后過(guò)期。但是這個(gè)簡(jiǎn)單的方法意味著緩存數(shù)據(jù)沒(méi)有保持與底層數(shù)據(jù)源的聯(lián)系,從而導(dǎo)致過(guò)期數(shù)據(jù)長(zhǎng)時(shí)保存或當(dāng)前數(shù)據(jù)很快過(guò)期。更好的方法是使用SqlCacheDependency類,這樣數(shù)據(jù)一直被緩存,直到其底層數(shù)據(jù)在SQL數(shù)據(jù)庫(kù)中被修改。本篇教程將講解怎樣使用這個(gè)類。Part1簡(jiǎn)介使用ObjectDataSource緩存數(shù)據(jù)和在架構(gòu)中緩存數(shù)據(jù)教程中探討的緩存技術(shù)使用基于時(shí)間的有效期,在指定的周期過(guò)后從緩存中清除數(shù)據(jù)。該方法是平衡緩存性能與數(shù)據(jù)過(guò)時(shí)的最簡(jiǎn)單的方法。選擇x秒的有效期,頁(yè)面開(kāi)發(fā)者雖然只能享受到x秒的緩存帶來(lái)的好處,但可高枕無(wú)憂,因?yàn)閿?shù)據(jù)的過(guò)期時(shí)間最多不會(huì)超過(guò)x秒。當(dāng)然,對(duì)于靜態(tài)數(shù)據(jù),x可以延長(zhǎng)為web應(yīng)用程序的生命周期,如應(yīng)用程序啟動(dòng)時(shí)緩存數(shù)據(jù)教程所述。緩存數(shù)據(jù)庫(kù)數(shù)據(jù)時(shí),人們常常會(huì)選用基于時(shí)間的有效期,因?yàn)槠湟子谑褂谩53_@不是個(gè)合適的方案。理想情況是:數(shù)據(jù)庫(kù)數(shù)據(jù)一直被緩存,直到底層數(shù)據(jù)在數(shù)據(jù)庫(kù)中被修改;此時(shí)才清除緩存。該方法能最大地獲得緩存帶來(lái)的性能上的好處,同時(shí)使過(guò)時(shí)數(shù)據(jù)保持的時(shí)間最短。然而,為享受到這些好處,必須建立一套系統(tǒng),該系統(tǒng)可以感知到底層數(shù)據(jù)庫(kù)數(shù)據(jù)發(fā)生了改變并從緩存中清除相應(yīng)的條目。在ASP.NET2.0以前,頁(yè)面開(kāi)發(fā)者負(fù)責(zé)實(shí)現(xiàn)該系統(tǒng)。ASP.NET2.0提供了SqlCacheDependency類以及必要的基礎(chǔ)架構(gòu),利用它們可以在數(shù)據(jù)庫(kù)發(fā)生了變化時(shí)感知到變化,從而清除相應(yīng)的緩存條目。有兩種技術(shù)可用于感知底層數(shù)據(jù)發(fā)生的變化:通知和輪詢。下面我們會(huì)討論通知和輪詢的不同之處,之后,我們將創(chuàng)建必要的基礎(chǔ)架構(gòu)來(lái)支持輪詢,然后探討怎樣通過(guò)聲明和編程兩種方式來(lái)使用SqlCacheDependency類。了解通知和輪詢有兩種技術(shù)可用于感知數(shù)據(jù)庫(kù)中的數(shù)據(jù)發(fā)生的變化:通知和輪詢。使用通知時(shí),對(duì)于某個(gè)具體查詢,如果自其上次執(zhí)行以來(lái)其查詢結(jié)果已發(fā)生了改變,數(shù)據(jù)庫(kù)會(huì)自動(dòng)通知ASP.NET運(yùn)行時(shí)。使用輪詢時(shí),數(shù)據(jù)庫(kù)服務(wù)器保存特定表最近發(fā)生更改時(shí)的信息。ASP.NET運(yùn)行時(shí)周期性地查詢數(shù)據(jù)庫(kù),看哪些表的數(shù)據(jù)在緩存后發(fā)生過(guò)改動(dòng)。其數(shù)據(jù)改動(dòng)過(guò)的那些表的相關(guān)緩存條目會(huì)被清除。選用通知技術(shù)時(shí),需要的建立工作比輪詢少,并且具有更細(xì)的粒度,因?yàn)樵摷夹g(shù)在查詢級(jí)而不是在表級(jí)跟蹤變化。遺憾的是,只有在MicrosoftSQLServer2005的完整版,即非速成(non-Express)版中,才能使用通知。而對(duì)于MicrosoftSQLServer從7.0到2005之間的所有版本,都可采用輪詢技術(shù)。由于這些教程使用的是SQLServer2005Express版,我們將集中探討建立和使用輪詢。有關(guān)SQLServer2005的通知功能的更多資料,請(qǐng)參考本教程末尾的更多閱讀材料部分。采用輪詢時(shí),需配置數(shù)據(jù)庫(kù),使其包含一個(gè)名為AspNet_SqlCacheTablesForChangeNotification的表,該表有三列-tableName、notificationCreated和changeId。對(duì)于那些在web應(yīng)用程序的SQL緩存依賴項(xiàng)中可能需要用到其數(shù)據(jù)的表,該表都有一條記錄與之對(duì)應(yīng)。tableName列指定表名,而notificationCreated指示將該記錄添加到表中時(shí)的日期和時(shí)間。changeld列為int類型,其初始值為0。每次修改對(duì)應(yīng)的表時(shí),其值遞增。除了AspNet_SqlCacheTablesForChangeNotification表之外,數(shù)據(jù)庫(kù)還需要對(duì)可能出現(xiàn)在SQL緩存依賴項(xiàng)中的每個(gè)表包含一個(gè)觸發(fā)器。每當(dāng)在AspNet_SqlCacheTablesForChangeNotification表中插入、更新、刪除一條記錄,或表中changeId值遞增時(shí),會(huì)執(zhí)行這些觸發(fā)器。在使用一個(gè)SqlCacheDependency對(duì)象緩存數(shù)據(jù)時(shí),ASP.NET運(yùn)行時(shí)會(huì)跟蹤相應(yīng)表的當(dāng)前changeId。系統(tǒng)周期性地檢查數(shù)據(jù)庫(kù),一旦發(fā)現(xiàn)某個(gè)SqlCacheDependency對(duì)象的changeId值不同于數(shù)據(jù)庫(kù)中的相應(yīng)值,就清除該對(duì)象,因?yàn)閏hangeId值不同意味著數(shù)據(jù)被緩存后相應(yīng)表又有了變化。步驟1:探討aspnet_regsql.exe命令行程序如上所述,使用輪詢方法時(shí),必須對(duì)數(shù)據(jù)庫(kù)進(jìn)行設(shè)置,使其包含下面的基礎(chǔ)架構(gòu):一個(gè)預(yù)先定義的表(AspNet_SqlCacheTablesForChangeNotification),一些存儲(chǔ)過(guò)程,以及web應(yīng)用程序中SQL緩存依賴項(xiàng)可能用到的各個(gè)表的觸發(fā)器。可通過(guò)命令行程序aspnet_regsql.exe來(lái)創(chuàng)建這些表、存儲(chǔ)過(guò)程和觸發(fā)器,該程序位于$WINDOWS$¥Microsoft.NET¥Framework¥version文件夾下。要?jiǎng)?chuàng)0建AspNet_SqlCacheTablesForChangeNotification表和相關(guān)的存儲(chǔ)過(guò)程,在命令行執(zhí)行以下命令:/*ForSQLServerauthentication...*/aspnet_regsql.exe-Sserver-Uuser-Ppassword-ddatabase-ed/*ForWindowsAuthentication...*/aspnet_regsql.exe-Sserver-E-ddatabase-ed注意:要執(zhí)行這些命令,指定的數(shù)據(jù)庫(kù)帳戶必須具有db_securityadmin和db_ddladmin身份。要了解aspnet_regsql.exe命令行程序發(fā)送給數(shù)據(jù)庫(kù)的T-SQL,請(qǐng)參閱此博客文章。例如,在Windows身份認(rèn)證模式下,對(duì)MicrosoftSQLServer數(shù)據(jù)庫(kù)服務(wù)器ScottsServer上的數(shù)據(jù)庫(kù)pubs添加輪詢的基礎(chǔ)架構(gòu)時(shí),進(jìn)入到相應(yīng)的目錄后在命令行中輸入:aspnet_regsql.exe-SScottsServer-E-dpubs-ed完成數(shù)據(jù)庫(kù)級(jí)基礎(chǔ)架構(gòu)的添加后,我們需要針對(duì)SQL緩存依賴項(xiàng)中要用到的那些表添加觸發(fā)器。再次使用aspnet_regsql.exe命令行程序,不過(guò)這次使用-t來(lái)指定表名,且將-ed替換為-et,如下:/*ForSQLServerauthentication...*/aspnet_regsql.exe-S<i>server</i>-U<i>user</i>-P<i>password</i>-d<i>database</i>-t<i>tableName</i>-et/*ForWindowsAuthentication...*/aspnet_regsql.exe-S<i>server</i>-E-d<i>database</i>-t<i>tableName</i>-et要對(duì)ScottsServer上的pubs數(shù)據(jù)庫(kù)中的authors和titles表添加觸發(fā)器,使用:aspnet_regsql.exe-SScottsServer-E-dpubs-tauthors-etaspnet_regsql.exe-SScottsServer-E-dpubs-ttitles-et對(duì)于本教程,要對(duì)Products、Categories和Suppliers表添加觸發(fā)器。我們將在步驟3中探討具體的命令行語(yǔ)句。步驟2:在App_Data中引用MicrosoftSQLServerExpress版數(shù)據(jù)庫(kù)在添加必要的輪詢基礎(chǔ)架構(gòu)時(shí),spnet_regsql.exe命令行程序需要數(shù)據(jù)庫(kù)和服務(wù)器的名稱。但是對(duì)于放在App_Data文件夾中的MicrosoftSQLServer2005Express數(shù)據(jù)庫(kù)而言,它的數(shù)據(jù)庫(kù)名和服務(wù)器名又是什么呢?沒(méi)有必要探究其數(shù)據(jù)庫(kù)名和服務(wù)器名到底是什么,我發(fā)現(xiàn)最簡(jiǎn)單的方法是用SQLServerManagementStudio來(lái)將該數(shù)據(jù)庫(kù)附加到localhost¥SQLExpress數(shù)據(jù)庫(kù)實(shí)例,并重命名該數(shù)據(jù)庫(kù)。如果您在計(jì)算機(jī)上安裝了SQLServer2005的一個(gè)完整版,則很可能也安裝了SQLServerManagementStudio。如果您安裝的是Express版本,可以下載免費(fèi)的MicrosoftSQLServerManagementStudioExpressEdition。首先,關(guān)閉VisualStudioo然后,打開(kāi)SQLServerManagementStudio,選擇使用WindowsAuthentication連接到localhost¥SQLExpress服務(wù)器。圖1:連接到localhost¥SQLExpress服務(wù)器連接到服務(wù)器后,ManagementStudio將顯示該服務(wù)器,其中有針對(duì)數(shù)據(jù)庫(kù)、安全等的子文件夾。右鍵單擊Databases文件夾并選擇Attach選項(xiàng)。這將彈出AttachDatabases對(duì)話框(參見(jiàn)圖2)。單擊Add按鈕,選擇您的web應(yīng)用程序的App_Data文件夾下的NORTHWND.MDF數(shù)據(jù)庫(kù)文件夾。圖2:附加App_Data文件夾下的NORTHWND.MDF數(shù)據(jù)庫(kù)這會(huì)將該數(shù)據(jù)庫(kù)添加到Databases文件夾。數(shù)據(jù)庫(kù)名可能是該數(shù)據(jù)庫(kù)文件的完整路徑或前面帶有一個(gè)GUID的完整路徑。為避免在使用aspnet_regsql.exe命令行工具時(shí)輸入該過(guò)長(zhǎng)的數(shù)據(jù)庫(kù)名,可通過(guò)右鍵單擊剛附加的數(shù)據(jù)庫(kù)并選擇Rename將該數(shù)據(jù)庫(kù)重命名為一個(gè)更友好的名稱。我將該數(shù)據(jù)庫(kù)重命名為“DataTutorials”。圖3:將附加的數(shù)據(jù)庫(kù)重命名為更友好的名稱步驟3:對(duì)Northwind數(shù)據(jù)庫(kù)添加輪詢基礎(chǔ)架構(gòu)現(xiàn)在我們已附加了App_Data文件夾下的NORTHWND.MDF數(shù)據(jù)庫(kù),可以開(kāi)始添加輪詢基礎(chǔ)架構(gòu)了。假定您已將該數(shù)據(jù)庫(kù)重命名為“DataTutorials”,執(zhí)行如下四個(gè)命令:aspnet_regsql.exe-Slocalhost\SQLExpress-E-dDataTutorials-edaspnet_regsql.exe-Slocalhost\SQLExpress-E-dDataTutorials-tProducts-etaspnet_regsql.exe-Slocalhost¥SQLExpress-E-dDataTutorials-tCategories-etaspnet_regsql.exe-Slocalhost¥SQLExpress-E-dDataTutorials-tSuppliers-et執(zhí)行這四個(gè)命令之后,在ManagementStudio中右鍵單擊該數(shù)據(jù)庫(kù)名,進(jìn)入Tasks子菜單,選擇Detach。然后關(guān)閉ManagementStudio,重新打開(kāi)VisualStudio。重新打開(kāi)VisualStudio后,在ServerExplorer中找到并展開(kāi)該數(shù)據(jù)庫(kù)。其中,可看到一個(gè)新表(AspNet_SqlCacheTablesForChangeNotification)、一些新的存儲(chǔ)過(guò)程以及Products、Categories和Suppliers表的觸發(fā)器。圖4:數(shù)據(jù)庫(kù)現(xiàn)在包含必需的輪詢基礎(chǔ)架構(gòu)步驟4:配置輪詢服務(wù)在數(shù)據(jù)庫(kù)中創(chuàng)建了所需的表、觸發(fā)器和存儲(chǔ)過(guò)程后,最后步驟是配置輪詢服務(wù),為此,在Web.config中指定要使用的數(shù)據(jù)庫(kù),以及輪詢頻率(單位為毫秒)。下面的標(biāo)記代碼指定每隔1秒輪詢一次Northwind數(shù)據(jù)庫(kù)。<?xmlversion="1.0"?><configuration><connectionStrings><addname="NORTHWNDConnectionString"connectionString="DataSource=.¥SQLEXPRESS;AttachDbFilename=|DataDirectory|¥NORTHWND.MDF;IntegratedSecurity二True;UserInstance=True"providerName="System.Data.SqlClient"/></connectionStrings><system.web>...<!--ConfigurethepollingserviceusedforSQLcachedependencies--><caching><sqlCacheDependencyenabled="true"pollTime="1000"><databases><addname="NorthwindDB"connectionStringName="NORTHWNDConnectionString"/></databases></sqlCacheDependency></caching></system.web></configuration><add>元素中的name值(“NorthwindDB”)是一個(gè)易讀的名稱,它對(duì)應(yīng)于一個(gè)具體的數(shù)據(jù)庫(kù)。使用SQL緩存依賴項(xiàng)時(shí),我們需要引用此處定義的數(shù)據(jù)庫(kù)名稱以及緩存數(shù)據(jù)所依賴的表。在步驟6中,我們將看到怎樣使用SqlCacheDependency類通過(guò)編碼將SQL緩存依賴項(xiàng)與緩存數(shù)據(jù)相關(guān)聯(lián)。一旦建立了SQL緩存依賴項(xiàng),輪詢系統(tǒng)將每隔pollTime毫秒連接到<databases>元素中定義的數(shù)據(jù)庫(kù),并執(zhí)行AspNet_SqlCachePollingStoredProcedure存儲(chǔ)過(guò)程。該存儲(chǔ)過(guò)程是在步驟3中使用aspnet_regsql.exe命令行工具添加的,它會(huì)返回AspNet_SqlCacheTablesForChangeNotificationeturns表中每條記錄的tableName和changeId值。過(guò)時(shí)的SQL緩存依賴項(xiàng)會(huì)從緩存中清除。應(yīng)在權(quán)衡性能和數(shù)據(jù)過(guò)時(shí)的基礎(chǔ)上設(shè)置pollTime。小的pollTime值雖然使對(duì)數(shù)據(jù)庫(kù)的請(qǐng)求次數(shù)增加,但能更快的將過(guò)時(shí)數(shù)據(jù)從緩存中清除。較大的pollTime值雖然減少了對(duì)數(shù)據(jù)庫(kù)的請(qǐng)求次數(shù),但增加了從后臺(tái)數(shù)據(jù)改變到清除相關(guān)緩存條目之間的延遲時(shí)間。還好,數(shù)據(jù)庫(kù)請(qǐng)求只是執(zhí)行一個(gè)簡(jiǎn)單的存儲(chǔ)過(guò)程,該存儲(chǔ)過(guò)程只是從一個(gè)簡(jiǎn)單的記錄數(shù)少的表返回不多的幾行。對(duì)您的應(yīng)用程序試用一些不同的pollTime值,從中找出一個(gè)可平衡數(shù)據(jù)庫(kù)訪問(wèn)和數(shù)據(jù)過(guò)時(shí)這兩者的理想值。允許的最小pollTime值為500。注意:上面的例子在<sqlCacheDependency>元素中指定了一個(gè)單一的pollTime,但您也可以隨意地在<add>元素中指定pollTime值。當(dāng)您指定了多個(gè)數(shù)據(jù)庫(kù)且想為每個(gè)數(shù)據(jù)庫(kù)都指定一個(gè)輪詢頻率時(shí),這樣做很有用。步驟5:通過(guò)聲明方式使用SQL緩存依賴項(xiàng)在步驟1到4中,我們探討了如何建立必需的數(shù)據(jù)庫(kù)基礎(chǔ)架構(gòu)并配置輪詢系統(tǒng)。有了這個(gè)基礎(chǔ)架構(gòu)后,現(xiàn)在我們可以通過(guò)編程或聲明技術(shù),在添加條目到數(shù)據(jù)緩存時(shí)使用相關(guān)的SQL緩存依賴項(xiàng)。在本步驟中,我們將探討如何以聲明的方式使用SQL緩存依賴項(xiàng)。在步驟6中,我們將探討編程的方式。使用ObjectDataSource緩存數(shù)據(jù)教程探討了ObjectDataSource的聲明方式的緩存功能。只要簡(jiǎn)單地將EnableCaching屬性設(shè)置為T(mén)rue,CacheDuration屬性設(shè)置為某個(gè)時(shí)間間隔,ObjectDataSource就會(huì)自動(dòng)地以指定間隔緩存從其底層對(duì)象返回的數(shù)據(jù)。ObjectDataSource還可使用一個(gè)或多個(gè)SQL緩存依賴項(xiàng)。下面我們演示怎樣以聲明方式使用SQL緩存依賴項(xiàng)。打開(kāi)Caching文件夾中的SqlCacheDependencies.aspx頁(yè)面,從Toolbox中將一個(gè)GridView控件拖放到設(shè)計(jì)器中。將該GridView的ID設(shè)置為ProductsDeclarative,從其智能標(biāo)簽中選擇相應(yīng)選項(xiàng),將其綁定到一個(gè)名為ProductsDataSourceDeclarative的新ObjectDataSource。圖5:創(chuàng)建一個(gè)名為ProductsDataSourceDeclarative的新ObjectDataSource配置該ObjectDataSource使用ProductsBLL類,在SELECT選項(xiàng)卡的下拉列表中選擇GetProductsO。在UPDATE選項(xiàng)卡中,選擇有三個(gè)輸入?yún)?shù)-productName、unitPrice和productID的UpdateProduct重載方法。在INSERT和DELETE選項(xiàng)卡的下拉列表中選擇“(None)”。圖6:選擇有三個(gè)輸入?yún)?shù)的UpdateProduct重載方法圖7:在INSERT和DELETE選項(xiàng)卡的下拉列表中選擇"(None)”完成ConfigureDataSource向?qū)Ш?,VisualStudio將為每個(gè)數(shù)據(jù)字段在GridView中創(chuàng)建BoundField和CheckBoxField。將ProductName、CategoryName和UnitPrice之外的所有字段刪除,并按您的意愿格式化這些字段。在GridView的智能標(biāo)簽中,選中EnablePaging、EnableSorting和EnableEditing復(fù)選框。VisualStudio會(huì)將ObjectDataSource的OldValuesParameterFormatString屬性設(shè)置為original」。}。為使GridView的編輯功能正常工作,要么從聲明語(yǔ)句中完全地刪除該屬性,要么將其設(shè)置為缺省值{0}。最后,在GridView上面添加一個(gè)LabelWeb控件,并將其ID屬性設(shè)置為ODSEvents,其EnableViewState屬性設(shè)置為False。完成這些改變后,頁(yè)面的聲明代碼應(yīng)類似如下。注意,我對(duì)GridView的各字段的外觀進(jìn)行了一些定制,這對(duì)于演示SQL緩存依賴項(xiàng)功能來(lái)說(shuō)并不是必要的。<asp:LabelID="ODSEvents"runat="server"EnableViewState="False"/><asp:GridViewID="ProductsDeclarative"runat="server"AutoGenerateColumns="False"DataKeyNames="ProductIDDataSourcelD="ProductsDataSourceDeclarative"AllowPaging="True"AllowSorting="True"><Columns><asp:CommandFieldShowEditButton="True"/><asp:TemplateFieldHeaderText="Product"SortExpression="ProductName"><EditItemTemplate><asp:TextBoxID="ProductName"runat="server"Text='<%#Bind("ProductName")%>'/><asp:RequiredFieldValidatorID="RequiredFieldValidator1"ControlToValidate="ProductName"Display="Dynamic"ErrorMessage="Youmustprovideanamefortheproduct."SetFocusOnError="True"runat="server">*</asp:RequiredFieldValidator></EditItemTemplate><ItemTemplate><asp:LabelID="Label2"runat="server"Text='<%#Bind("ProductName")%>'/></ItemTemplate></asp:TemplateField><asp:BoundFieldDataField="CategoryName"HeaderText="Category"ReadOnly="True"SortExpression="CategoryName"/><asp:TemplateFieldHeaderText="Price"SortExpression="UnitPrice"><EditItemTemplate>$<asp:TextBoxID="UnitPrice"runat="server"Columns="8"Text='<%#Bind("UnitPrice","{0:N2}")%>'></asp:TextBox><asp:CompareValidatorID="CompareValidator1"runat="server"ControlToValidate="UnitPrice"ErrorMessage="Youmustenteravalidcurrencyvaluewithnocurrencysymbols.Also,thevaluemustbegreaterthanorequaltozero."Operator="GreaterThanEqual"SetFocusOnError="True"Type="Currency"Display="Dynamic"ValueToCompare="0">*</asp:CompareValidator></EditItemTemplate><ItemStyleHorizontalAlign="Right"/><ItemTemplate><asp:LabelID="Labell"runat="server"Text='<%#Bind("UnitPrice","{0:c}")%>'/></ItemTemplate></asp:TemplateField></Columns></asp:GridView><asp:ObjectDataSourceID="ProductsDataSourceDeclarative"runat="server"SelectMethod="GetProducts"TypeName="ProductsBLL"UpdateMethod="UpdateProduct"><UpdateParameters><asp:ParameterName="productName"Type="String"/><asp:ParameterName="unitPrice"Type="Decimal"/><asp:ParameterName="productID"Type="Int32"/></UpdateParameters></asp:ObjectDataSource>Part2接下來(lái),為ObjectDataSource的Selecting事件創(chuàng)建一個(gè)事件處理器,并在其中添加如下代碼:larative_SelectingSelectingEventArgse)ventfired";我們知道,只有當(dāng)ObjectDataSource從其底層對(duì)象獲取數(shù)據(jù)時(shí),才會(huì)觸發(fā)它的Selecting事件。如果ObjectDataSource從自己的緩存中訪問(wèn)數(shù)據(jù),則不會(huì)觸發(fā)該事件。現(xiàn)在從瀏覽器訪問(wèn)該頁(yè)面。由于我們還未實(shí)現(xiàn)緩存,每次對(duì)網(wǎng)格進(jìn)行分頁(yè)、排序或編輯時(shí),頁(yè)面都會(huì)顯示文本“Selectingeventfi「e如圖8所示。

圖8:每次對(duì)GridView進(jìn)行分頁(yè)、編輯或排序時(shí)觸發(fā)ObjectDataSource的Selecting事件在使用ObjectDataSource緩存數(shù)據(jù)教程中講過(guò),如果EnableCaching屬性設(shè)置為true,ObjectDataSource會(huì)將數(shù)據(jù)緩存,并在CacheDuration屬性指定的時(shí)間內(nèi)維持緩存數(shù)據(jù)。ObjectDataSource還有一個(gè)SqlCacheDependency屬性,該屬性可以通過(guò)以下模式為緩存數(shù)據(jù)添加一個(gè)或多個(gè)SQL緩存依賴項(xiàng):databaseName1:tableName1;databaseName2:tableName2;...其中,databaseName是Web.config中<add>元素的name屬性中指定的數(shù)據(jù)軍名,tableName為數(shù)據(jù)庫(kù)表名。例如,要?jiǎng)?chuàng)建這樣一^個(gè)ObjectDataSource,它使用基于Northwind的Products表的SQL緩存依賴項(xiàng)來(lái)緩存數(shù)據(jù),緩存數(shù)據(jù)的時(shí)間不限,我們需將ObjectDataSource的EnableCaching屬性設(shè)置為T(mén)rue,其SqlCacheDependency屬性設(shè)置為“NorthwindDB:Products”注意:可以同時(shí)使用SQL緩存依賴項(xiàng)和基于時(shí)間的有效期,方法是,將EnableCaching設(shè)置為T(mén)rue、CacheDuration設(shè)置為所需時(shí)間間隔、SqlCacheDependency設(shè)置為數(shù)據(jù)庫(kù)名和表名。不管是基于時(shí)間的有效期到期還是輪詢系統(tǒng)發(fā)現(xiàn)底層數(shù)據(jù)庫(kù)數(shù)據(jù)發(fā)生改變,ObjectDataSource都會(huì)清除其數(shù)據(jù)。SqlCacheDependencies.aspx頁(yè)面中的GridView顯示的數(shù)據(jù)來(lái)自兩張表-Products和Categories(產(chǎn)品的CategoryName字段通過(guò)JOINonCategories獲得)。因此,我們想指定兩個(gè)SQL緩存依賴項(xiàng):“NorthwindDB:Products;NorthwindDB:Categories”(1)The,?(1)The,?SelectingEventFired"textisnotpresentasthedataisbeingservedfromthecachen(Ucb頑S dtfSQLCxlwDependencies 、S?rthWorkingwithDataTutoriah富《心UsingSQLCacheDependencies(2)TheProduct"ChaiTea”isUpdatedfromtheBasics.aspxpage?0?**-> ?::. C?,匕?C、g??ta>amw>?QeEditir>9^ndC>eletin9DatafromaGrklVMvfAOfiCSf1 CiwYmi[I1[10 ?TOU*9?血 a crwngI1?4-HWEJ1QtiEte3 AhmMSvhjc1212-WOEddTOM血Qtftlfl4 fhdf3577■??a"EAXOfiftlfi5 CMe*morv?c^oon^r<24?twin匚A!Mate CIO|iicrt>erry)212-BMJMrw?<>(3)ReturningtotheFirstPageinSqlCacheDependencies.aspxredisplaystheSefectingEventFired”textsincethecacheddatawasevictedwhentheProductstablewasupdatedinStep2圖9:配置ObjectDataSource支持緩存且使用基于Products和Categories的SQL緩存依賴項(xiàng)配置ObjectDataSource支持緩存后,通過(guò)瀏覽器再次訪問(wèn)該頁(yè)面。首次訪問(wèn)頁(yè)面時(shí),會(huì)出現(xiàn)“Selectingeventfired”文本,但進(jìn)行翻頁(yè)、排序或單擊Edit或Cancel按鈕時(shí),該文本會(huì)消失。這是因?yàn)閿?shù)據(jù)裝載至I]ObjectDataSource的緩存中后,它一直在那兒,直到Products或Categories表發(fā)生改變或通過(guò)GridView對(duì)數(shù)據(jù)進(jìn)行了更新。翻頁(yè)顯示網(wǎng)格,此時(shí)"Selectingeventfired”沒(méi)有出現(xiàn)。接著,另外打開(kāi)一個(gè)新的瀏覽器窗口并導(dǎo)航到Basics教程的編輯、插入和刪除部分中的Basics.aspx頁(yè)面(~/EditInsertDelete/Basics.aspx)。更新某產(chǎn)品的名稱或價(jià)格。然后,從第一個(gè)瀏覽器窗口查看另一個(gè)不同的數(shù)據(jù)頁(yè)、對(duì)網(wǎng)格進(jìn)行排序或單擊某行的Edit按鈕。這次,"Selectingeventfired"又出現(xiàn)了,因?yàn)榈讓訑?shù)據(jù)庫(kù)數(shù)據(jù)已更改(參見(jiàn)圖10)。如果該文本沒(méi)有出現(xiàn)稍等后重試。我們知道,輪詢服務(wù)每隔pollTime毫秒檢測(cè)一次Products表的變化,因此在底層數(shù)據(jù)的更新和緩存數(shù)據(jù)的清除之間有一個(gè)延遲。(1)The,?(1)The,?SelectingEventFired"textisnotpresentasthedataisbeingservedfromthecachen(Ucb頑S dtfSQLCxlwDependencies 、S?rthWorkingwithDataTutoriah富《心UsingSQLCacheDependencies(2)TheProduct"ChaiTea”isUpdatedfromtheBasics.aspxpage?0?**-> ?::. C?,匕?C、g??ta>amw>?QeEditir>9^ndC>eletin9DatafromaGrklVMvfAOfiCSf1 CiwYmi[I1[10 ?TOU*9?血 a crwngI1?4-HWEJ1QtiEte3 AhmMSvhjc1212-WOEddTOM血Qtftlfl4 fhdf3577■??a"EAXOfiftlfi5 CMe*morv?c^oon^r<24?twin匚A!Mate CIO|iicrt>erry)212-BMJMrw?<>(3)ReturningtotheFirstPageinSqlCacheDependencies.aspxredisplaystheSefectingEventFired”textsincethecacheddatawasevictedwhentheProductstablewasupdatedinStep2圖10:修改Products表會(huì)清除緩存的產(chǎn)品數(shù)據(jù)步驟6:通過(guò)編程方式使用SqlCacheDependency類在架構(gòu)中緩存數(shù)據(jù)教程講述了在架構(gòu)中使用一個(gè)單獨(dú)的緩存層的好處,這勝過(guò)了緩存功能與ObjectDataSource緊密結(jié)合的情況。在那個(gè)教程中,我門(mén)創(chuàng)建了一個(gè)ProductsCL類來(lái)演示怎樣以編程的方式進(jìn)行數(shù)據(jù)緩存。要在緩存層使用SQL緩存依賴項(xiàng),要使用SqlCacheDependency類。在輪詢系統(tǒng)中,一個(gè)SqlCacheDependency對(duì)象必須與某個(gè)具體的數(shù)據(jù)庫(kù)和表相關(guān)聯(lián)。例如,下面的代碼創(chuàng)建了一^基于Northwind數(shù)據(jù)庫(kù)的Products表的SqlCacheDependency對(duì)象:ableDependency=NorthwindDB”,"Products");SqlCacheDependency的構(gòu)造函數(shù)的兩個(gè)輸入?yún)?shù)分別是數(shù)據(jù)庫(kù)名和表名。與ObjectDataSource的SqlCacheDependency屬性類似,使用的數(shù)據(jù)庫(kù)名是Web.config文件中<add>元素的name屬性指定的值。表名是實(shí)際的數(shù)據(jù)庫(kù)表名。要將一個(gè)SqlCacheDependency與一個(gè)添加到數(shù)據(jù)緩存中的條目相關(guān)聯(lián),可以使用一個(gè)接受依賴項(xiàng)的Insert重載方法。下面的代碼將value添加到數(shù)據(jù)緩存中,緩存時(shí)間不限,并將它基于Products表的SqlCacheDependency相關(guān)聯(lián)。換言之,value會(huì)一直保持在緩存中,直到由于內(nèi)存不足或輪詢系統(tǒng)檢測(cè)到Products表在緩存后發(fā)生了改變才被清除。ableDependency=NorthwindDB","Products");,e.NoAbsoluteExpiration,e.NoSlidingExpiration);目前,緩存層的ProductsCL類緩存Products表的數(shù)據(jù),基于時(shí)間的有效期為60秒。我們對(duì)該類進(jìn)行更新,使其使用SQL緩存依賴項(xiàng)。ProductsCL類的AddCacheltem方法負(fù)責(zé)將數(shù)據(jù)添加至I]緩存,目前它包含下面的代碼:Key,objectvalue)he=HttpRuntime.Cache;[0]isinthecache]=DateTime.Now;cy=newCaching.CacheDependency(null,MasterCachDataCache.Insert(GetCacheKey(rawKey),value,depDateTime.Now.AddSeconds(CacheDuration),System.Web.Caching.Cache.NoSlidingExpiration}更新該代碼,用一^個(gè)SqlCacheDependency對(duì)象來(lái)替換掉MasterCacheKeyArray緩存依賴項(xiàng):Key,objectvalue)he=HttpRuntime.Cache;jectsforProductsctsTableDependency=cy("NorthwindDB","Products");eusingproductsTableDependencyDataCache.Insert(GetCacheKey(rawKey),value,proCaching.Cache.NoAbsoluteExpiration,Caching.}為了測(cè)試該功能,在頁(yè)面已有的ProductsDeclarativeGridView下面另外添加一個(gè)GridView。將該新GridView的ID設(shè)置為ProductsProgrammatic,通過(guò)其智能標(biāo)簽將其綁定到一^新的名為ProductsDataSourceProgrammatic的ObjectDataSource。配置該ObjectDataSource使用ProductsCL類在SELECT和UPDATE選項(xiàng)卡的下拉列表中分別選擇GetProducts和UpdateProduct。

圖11:配置ObjectDataSource使用ProductsCL類

圖12:在SELECT選項(xiàng)卡的下拉列表中選擇GetProducts方法圖13:在UPDATE選項(xiàng)卡的下拉列表中選擇UpdateProduct方法完成ConfigureDataSource向?qū)Ш螅琕isualStudio將為每個(gè)數(shù)據(jù)字段在GridView中創(chuàng)建BoundField和CheckBoxField。與添加到該頁(yè)的第一^個(gè)GridView一樣,將ProductName、CategoryName和UnitPrice之外的所有字段刪除,并按照您的意愿格式化這些字段。在GridView的智能標(biāo)簽中,選中EnablePaging、EnableSorting和EnableEditing復(fù)選框。與ProductsDataSourceDeclarativeObjectDataSource一樣,VisualStudio會(huì)將ProductsDataSourceProgrammaticObjectDataSource的OldValuesParameterFormatString屬性設(shè)置為original_{0}。為使GridView的編輯功能正常工作,將該屬性置回{0}(或從聲明語(yǔ)句中完全地刪除該屬性賦值)。完成這些任務(wù)后,最終的GridView和ObjectDataSource聲明代碼類似如下:ic"runat="server"KeyNames="ProductID”P(pán)rogrammatic"AllowPaging="Truetton="True"/>t="Product"SortExpression="ProductName">ductName"runat="server"Text='<%#Bind("ProductName")%><asp:RequiredFieldValidatorID="RequControlToValidate="ProductName"ErrorMessage="YoumustprovideaSetFocusOnError="True"runat="server">*</asp:RequiredFi</EditItemTemplate><ItemTemplate><asp:LabelID="Label2"runat="serverText='<%#Bind("ProductName")%></ItemTemplate></asp:TemplateField><asp:BoundFieldDataField="CategoryName"HeaReadOnly="True"SortExpression="Category<asp:TemplateFieldHeaderText="Price"SortEx<EditItemTemplate>$<asp:TextBoxID="UnitPrice"runat="Text='<%#Bind("UnitPrice”,"{0:<asp:CompareValidatorID="CompareValControlToValidate="UnitPrice"DiErrorMessage="Youmustenteravnocurrencysymbols.Also,torequaltozero."Operator="GreaterThanEqual"SetFType="Currency"ValueToCompare="</EditItemTemplate><ItemStyleHorizontalAlign="Right"/><ItemTemplate><asp:LabelID="Label1"runat="serverText='<%#Bind("UnitPrice”,"{0:</ItemTemplate></asp:TemplateField></Columns></asp:GridView><asp:ObjectDataSourceID="ProductsDataSourceProgrammOldValuesParameterFormatString="{0}"SelectMethoTypeName="ProductsCL"UpdateMethod="UpdateProduc<UpdateParameters><asp:ParameterName="productName"Type="Stri<asp:ParameterName="unitPrice"Type="Decima<asp:ParameterName="productID"Type="Int32"</UpdateParameters></asp:ObjectDataSource>為測(cè)試緩存層中的SQL緩存依賴項(xiàng),在ProductCL類的AddCacheltem方法中設(shè)置一個(gè)斷點(diǎn),然后啟動(dòng)調(diào)試。首次訪問(wèn)SqlCacheDependencies.aspx時(shí),會(huì)觸發(fā)斷點(diǎn),因?yàn)槭鞘状握?qǐng)求數(shù)據(jù),且數(shù)據(jù)會(huì)被放入緩存中。接下來(lái),在GridView中跳轉(zhuǎn)到另一頁(yè)或?qū)δ硞€(gè)列進(jìn)行排序。這會(huì)導(dǎo)致GridView查詢數(shù)據(jù),由于Products數(shù)據(jù)庫(kù)表尚未改動(dòng),會(huì)在緩存中找到數(shù)據(jù)。如果反復(fù)在緩存中找不到數(shù)據(jù),確保您機(jī)器上有足夠可用的內(nèi)存,然后重試。在GridView里跳轉(zhuǎn)幾頁(yè),打開(kāi)另一個(gè)瀏覽器窗口,導(dǎo)航到Basics教程的編輯、插入和刪除部分中的Basics.aspx頁(yè)面(~/EditInsertDelete/Basics.aspx)。更新Products表的一條記錄,然后從第一個(gè)瀏覽器窗口查看一個(gè)新頁(yè)或單擊一個(gè)排序標(biāo)題。此時(shí),會(huì)遇到以下兩種情況之一:要么觸發(fā)斷點(diǎn),這意味著緩存數(shù)據(jù)由于數(shù)據(jù)庫(kù)發(fā)生變化而被清除;要么不觸發(fā)斷點(diǎn),意味著SqlCacheDependencies.aspx顯示的是過(guò)時(shí)的數(shù)據(jù)。如果沒(méi)有觸發(fā)斷點(diǎn),很可能是由于數(shù)據(jù)變化后還未觸發(fā)輪詢服務(wù)。我們知道,輪詢服務(wù)每隔pollTime毫秒檢測(cè)一次Products表的變化,因此在底層數(shù)據(jù)的更新和緩存數(shù)據(jù)的清除之間有一個(gè)延遲。注意:通過(guò)SqlCacheDependencies.aspx中的GridView編輯某個(gè)產(chǎn)品時(shí)很可能會(huì)產(chǎn)生該延遲。在架構(gòu)中緩存數(shù)據(jù)教程中,我們添加了MasterCacheKeyArray緩存依賴項(xiàng)以確保通過(guò)ProductsCL類的UpdateProduct方法編輯的數(shù)據(jù)會(huì)從緩存中清除。然而在本步驟開(kāi)始時(shí),我們?cè)谛薷腁ddCacheItem方法時(shí)替換了該緩存依賴項(xiàng),因此ProductsCL類會(huì)繼續(xù)顯示緩存的數(shù)據(jù),直到輪詢系統(tǒng)發(fā)現(xiàn)Products表的變化。我們將在步驟7中了解怎樣重新引入MasterCacheKeyArray緩存依賴項(xiàng)。步驟7:將一個(gè)緩存條目與多個(gè)依賴項(xiàng)相關(guān)聯(lián)我們知道,MasterCacheKeyArray緩存依賴項(xiàng)用于確保在緩存中與產(chǎn)品相關(guān)的所有條目中,只要其中一條的相關(guān)數(shù)據(jù)發(fā)生更改,所有與產(chǎn)品相關(guān)的數(shù)據(jù)都會(huì)從緩存清除。例如,GetProductsByCategorylDCategoryD)方法對(duì)每個(gè)獨(dú)特的categorylD值緩存多個(gè)ProductsDataTables實(shí)例。如果其中一個(gè)對(duì)象被清除,MasterCacheKeyArray緩存依賴項(xiàng)會(huì)確保其它對(duì)象也被清除。如果沒(méi)有該緩存依賴項(xiàng),就會(huì)存在這種可能性,當(dāng)緩存的數(shù)據(jù)被修改后,其它緩存的產(chǎn)品數(shù)據(jù)可能過(guò)時(shí)。因此,在使用SQL緩存依賴項(xiàng)的時(shí)候保持MasterCacheKeyArray緩存依賴項(xiàng)是很重要的。然而,數(shù)據(jù)緩存的Insert方法只允許一個(gè)依賴項(xiàng)對(duì)象。此外,在使用SQL緩存依賴項(xiàng)時(shí),我們可能要依賴多個(gè)數(shù)據(jù)庫(kù)表。例如,在ProductsCL類中緩存的ProductsDataTable包含每個(gè)產(chǎn)品的分類名稱和供/

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論