




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
本文档是VisualC#教程(切换到VisualBasic教程)最简单的缓存策略就是使缓存数据在一个指定的时间周期后过期。但是这个简单的方法意味着缓存数据没有保持与底层数据源的联系,从而导致过期数据长时保存或当前数据很快过期。更好的方法是使用SqlCacheDependency类,这样数据一直被缓存,直到其底层数据在SQL数据库中被修改。本篇教程将讲解怎样使用这个类。Part1简介使用ObjectDataSource缓存数据和在架构中缓存数据教程中探讨的缓存技术使用基于时间的有效期,在指定的周期过后从缓存中清除数据。该方法是平衡缓存性能与数据过时的最简单的方法。选择x秒的有效期,页面开发者虽然只能享受到x秒的缓存带来的好处,但可高枕无忧,因为数据的过期时间最多不会超过x秒。当然,对于静态数据,x可以延长为web应用程序的生命周期,如应用程序启动时缓存数据教程所述。缓存数据库数据时,人们常常会选用基于时间的有效期,因为其易于使用。但常常这不是个合适的方案。理想情况是:数据库数据一直被缓存,直到底层数据在数据库中被修改;此时才清除缓存。该方法能最大地获得缓存带来的性能上的好处,同时使过时数据保持的时间最短。然而,为享受到这些好处,必须建立一套系统,该系统可以感知到底层数据库数据发生了改变并从缓存中清除相应的条目。在ASP.NET2.0以前,页面开发者负责实现该系统。ASP.NET2.0提供了SqlCacheDependency类以及必要的基础架构,利用它们可以在数据库发生了变化时感知到变化,从而清除相应的缓存条目。有两种技术可用于感知底层数据发生的变化:通知和轮询。下面我们会讨论通知和轮询的不同之处,之后,我们将创建必要的基础架构来支持轮询,然后探讨怎样通过声明和编程两种方式来使用SqlCacheDependency类。了解通知和轮询有两种技术可用于感知数据库中的数据发生的变化:通知和轮询。使用通知时,对于某个具体查询,如果自其上次执行以来其查询结果已发生了改变,数据库会自动通知ASP.NET运行时。使用轮询时,数据库服务器保存特定表最近发生更改时的信息。ASP.NET运行时周期性地查询数据库,看哪些表的数据在缓存后发生过改动。其数据改动过的那些表的相关缓存条目会被清除。选用通知技术时,需要的建立工作比轮询少,并且具有更细的粒度,因为该技术在查询级而不是在表级跟踪变化。遗憾的是,只有在MicrosoftSQLServer2005的完整版,即非速成(non-Express)版中,才能使用通知。而对于MicrosoftSQLServer从7.0到2005之间的所有版本,都可采用轮询技术。由于这些教程使用的是SQLServer2005Express版,我们将集中探讨建立和使用轮询。有关SQLServer2005的通知功能的更多资料,请参考本教程末尾的更多阅读材料部分。采用轮询时,需配置数据库,使其包含一个名为AspNet_SqlCacheTablesForChangeNotification的表,该表有三列-tableName、notificationCreated和changeId。对于那些在web应用程序的SQL缓存依赖项中可能需要用到其数据的表,该表都有一条记录与之对应。tableName列指定表名,而notificationCreated指示将该记录添加到表中时的日期和时间。changeld列为int类型,其初始值为0。每次修改对应的表时,其值递增。除了AspNet_SqlCacheTablesForChangeNotification表之外,数据库还需要对可能出现在SQL缓存依赖项中的每个表包含一个触发器。每当在AspNet_SqlCacheTablesForChangeNotification表中插入、更新、删除一条记录,或表中changeId值递增时,会执行这些触发器。在使用一个SqlCacheDependency对象缓存数据时,ASP.NET运行时会跟踪相应表的当前changeId。系统周期性地检查数据库,一旦发现某个SqlCacheDependency对象的changeId值不同于数据库中的相应值,就清除该对象,因为changeId值不同意味着数据被缓存后相应表又有了变化。步骤1:探讨aspnet_regsql.exe命令行程序如上所述,使用轮询方法时,必须对数据库进行设置,使其包含下面的基础架构:一个预先定义的表(AspNet_SqlCacheTablesForChangeNotification),一些存储过程,以及web应用程序中SQL缓存依赖项可能用到的各个表的触发器。可通过命令行程序aspnet_regsql.exe来创建这些表、存储过程和触发器,该程序位于$WINDOWS$¥Microsoft.NET¥Framework¥version文件夹下。要创0建AspNet_SqlCacheTablesForChangeNotification表和相关的存储过程,在命令行执行以下命令:/*ForSQLServerauthentication...*/aspnet_regsql.exe-Sserver-Uuser-Ppassword-ddatabase-ed/*ForWindowsAuthentication...*/aspnet_regsql.exe-Sserver-E-ddatabase-ed注意:要执行这些命令,指定的数据库帐户必须具有db_securityadmin和db_ddladmin身份。要了解aspnet_regsql.exe命令行程序发送给数据库的T-SQL,请参阅此博客文章。例如,在Windows身份认证模式下,对MicrosoftSQLServer数据库服务器ScottsServer上的数据库pubs添加轮询的基础架构时,进入到相应的目录后在命令行中输入:aspnet_regsql.exe-SScottsServer-E-dpubs-ed完成数据库级基础架构的添加后,我们需要针对SQL缓存依赖项中要用到的那些表添加触发器。再次使用aspnet_regsql.exe命令行程序,不过这次使用-t来指定表名,且将-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要对ScottsServer上的pubs数据库中的authors和titles表添加触发器,使用:aspnet_regsql.exe-SScottsServer-E-dpubs-tauthors-etaspnet_regsql.exe-SScottsServer-E-dpubs-ttitles-et对于本教程,要对Products、Categories和Suppliers表添加触发器。我们将在步骤3中探讨具体的命令行语句。步骤2:在App_Data中引用MicrosoftSQLServerExpress版数据库在添加必要的轮询基础架构时,spnet_regsql.exe命令行程序需要数据库和服务器的名称。但是对于放在App_Data文件夹中的MicrosoftSQLServer2005Express数据库而言,它的数据库名和服务器名又是什么呢?没有必要探究其数据库名和服务器名到底是什么,我发现最简单的方法是用SQLServerManagementStudio来将该数据库附加到localhost¥SQLExpress数据库实例,并重命名该数据库。如果您在计算机上安装了SQLServer2005的一个完整版,则很可能也安装了SQLServerManagementStudio。如果您安装的是Express版本,可以下载免费的MicrosoftSQLServerManagementStudioExpressEdition。首先,关闭VisualStudioo然后,打开SQLServerManagementStudio,选择使用WindowsAuthentication连接到localhost¥SQLExpress服务器。图1:连接到localhost¥SQLExpress服务器连接到服务器后,ManagementStudio将显示该服务器,其中有针对数据库、安全等的子文件夹。右键单击Databases文件夹并选择Attach选项。这将弹出AttachDatabases对话框(参见图2)。单击Add按钮,选择您的web应用程序的App_Data文件夹下的NORTHWND.MDF数据库文件夹。图2:附加App_Data文件夹下的NORTHWND.MDF数据库这会将该数据库添加到Databases文件夹。数据库名可能是该数据库文件的完整路径或前面带有一个GUID的完整路径。为避免在使用aspnet_regsql.exe命令行工具时输入该过长的数据库名,可通过右键单击刚附加的数据库并选择Rename将该数据库重命名为一个更友好的名称。我将该数据库重命名为“DataTutorials”。图3:将附加的数据库重命名为更友好的名称步骤3:对Northwind数据库添加轮询基础架构现在我们已附加了App_Data文件夹下的NORTHWND.MDF数据库,可以开始添加轮询基础架构了。假定您已将该数据库重命名为“DataTutorials”,执行如下四个命令: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执行这四个命令之后,在ManagementStudio中右键单击该数据库名,进入Tasks子菜单,选择Detach。然后关闭ManagementStudio,重新打开VisualStudio。重新打开VisualStudio后,在ServerExplorer中找到并展开该数据库。其中,可看到一个新表(AspNet_SqlCacheTablesForChangeNotification)、一些新的存储过程以及Products、Categories和Suppliers表的触发器。图4:数据库现在包含必需的轮询基础架构步骤4:配置轮询服务在数据库中创建了所需的表、触发器和存储过程后,最后步骤是配置轮询服务,为此,在Web.config中指定要使用的数据库,以及轮询频率(单位为毫秒)。下面的标记代码指定每隔1秒轮询一次Northwind数据库。<?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”)是一个易读的名称,它对应于一个具体的数据库。使用SQL缓存依赖项时,我们需要引用此处定义的数据库名称以及缓存数据所依赖的表。在步骤6中,我们将看到怎样使用SqlCacheDependency类通过编码将SQL缓存依赖项与缓存数据相关联。一旦建立了SQL缓存依赖项,轮询系统将每隔pollTime毫秒连接到<databases>元素中定义的数据库,并执行AspNet_SqlCachePollingStoredProcedure存储过程。该存储过程是在步骤3中使用aspnet_regsql.exe命令行工具添加的,它会返回AspNet_SqlCacheTablesForChangeNotificationeturns表中每条记录的tableName和changeId值。过时的SQL缓存依赖项会从缓存中清除。应在权衡性能和数据过时的基础上设置pollTime。小的pollTime值虽然使对数据库的请求次数增加,但能更快的将过时数据从缓存中清除。较大的pollTime值虽然减少了对数据库的请求次数,但增加了从后台数据改变到清除相关缓存条目之间的延迟时间。还好,数据库请求只是执行一个简单的存储过程,该存储过程只是从一个简单的记录数少的表返回不多的几行。对您的应用程序试用一些不同的pollTime值,从中找出一个可平衡数据库访问和数据过时这两者的理想值。允许的最小pollTime值为500。注意:上面的例子在<sqlCacheDependency>元素中指定了一个单一的pollTime,但您也可以随意地在<add>元素中指定pollTime值。当您指定了多个数据库且想为每个数据库都指定一个轮询频率时,这样做很有用。步骤5:通过声明方式使用SQL缓存依赖项在步骤1到4中,我们探讨了如何建立必需的数据库基础架构并配置轮询系统。有了这个基础架构后,现在我们可以通过编程或声明技术,在添加条目到数据缓存时使用相关的SQL缓存依赖项。在本步骤中,我们将探讨如何以声明的方式使用SQL缓存依赖项。在步骤6中,我们将探讨编程的方式。使用ObjectDataSource缓存数据教程探讨了ObjectDataSource的声明方式的缓存功能。只要简单地将EnableCaching属性设置为True,CacheDuration属性设置为某个时间间隔,ObjectDataSource就会自动地以指定间隔缓存从其底层对象返回的数据。ObjectDataSource还可使用一个或多个SQL缓存依赖项。下面我们演示怎样以声明方式使用SQL缓存依赖项。打开Caching文件夹中的SqlCacheDependencies.aspx页面,从Toolbox中将一个GridView控件拖放到设计器中。将该GridView的ID设置为ProductsDeclarative,从其智能标签中选择相应选项,将其绑定到一个名为ProductsDataSourceDeclarative的新ObjectDataSource。图5:创建一个名为ProductsDataSourceDeclarative的新ObjectDataSource配置该ObjectDataSource使用ProductsBLL类,在SELECT选项卡的下拉列表中选择GetProductsO。在UPDATE选项卡中,选择有三个输入参数-productName、unitPrice和productID的UpdateProduct重载方法。在INSERT和DELETE选项卡的下拉列表中选择“(None)”。图6:选择有三个输入参数的UpdateProduct重载方法图7:在INSERT和DELETE选项卡的下拉列表中选择"(None)”完成ConfigureDataSource向导后,VisualStudio将为每个数据字段在GridView中创建BoundField和CheckBoxField。将ProductName、CategoryName和UnitPrice之外的所有字段删除,并按您的意愿格式化这些字段。在GridView的智能标签中,选中EnablePaging、EnableSorting和EnableEditing复选框。VisualStudio会将ObjectDataSource的OldValuesParameterFormatString属性设置为original」。}。为使GridView的编辑功能正常工作,要么从声明语句中完全地删除该属性,要么将其设置为缺省值{0}。最后,在GridView上面添加一个LabelWeb控件,并将其ID属性设置为ODSEvents,其EnableViewState属性设置为False。完成这些改变后,页面的声明代码应类似如下。注意,我对GridView的各字段的外观进行了一些定制,这对于演示SQL缓存依赖项功能来说并不是必要的。<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接下来,为ObjectDataSource的Selecting事件创建一个事件处理器,并在其中添加如下代码:larative_SelectingSelectingEventArgse)ventfired";我们知道,只有当ObjectDataSource从其底层对象获取数据时,才会触发它的Selecting事件。如果ObjectDataSource从自己的缓存中访问数据,则不会触发该事件。现在从浏览器访问该页面。由于我们还未实现缓存,每次对网格进行分页、排序或编辑时,页面都会显示文本“Selectingeventfi「e如图8所示。
图8:每次对GridView进行分页、编辑或排序时触发ObjectDataSource的Selecting事件在使用ObjectDataSource缓存数据教程中讲过,如果EnableCaching属性设置为true,ObjectDataSource会将数据缓存,并在CacheDuration属性指定的时间内维持缓存数据。ObjectDataSource还有一个SqlCacheDependency属性,该属性可以通过以下模式为缓存数据添加一个或多个SQL缓存依赖项:databaseName1:tableName1;databaseName2:tableName2;...其中,databaseName是Web.config中<add>元素的name属性中指定的数据军名,tableName为数据库表名。例如,要创建这样一^个ObjectDataSource,它使用基于Northwind的Products表的SQL缓存依赖项来缓存数据,缓存数据的时间不限,我们需将ObjectDataSource的EnableCaching属性设置为True,其SqlCacheDependency属性设置为“NorthwindDB:Products”注意:可以同时使用SQL缓存依赖项和基于时间的有效期,方法是,将EnableCaching设置为True、CacheDuration设置为所需时间间隔、SqlCacheDependency设置为数据库名和表名。不管是基于时间的有效期到期还是轮询系统发现底层数据库数据发生改变,ObjectDataSource都会清除其数据。SqlCacheDependencies.aspx页面中的GridView显示的数据来自两张表-Products和Categories(产品的CategoryName字段通过JOINonCategories获得)。因此,我们想指定两个SQL缓存依赖项:“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缓存依赖项配置ObjectDataSource支持缓存后,通过浏览器再次访问该页面。首次访问页面时,会出现“Selectingeventfired”文本,但进行翻页、排序或单击Edit或Cancel按钮时,该文本会消失。这是因为数据装载至I]ObjectDataSource的缓存中后,它一直在那儿,直到Products或Categories表发生改变或通过GridView对数据进行了更新。翻页显示网格,此时"Selectingeventfired”没有出现。接着,另外打开一个新的浏览器窗口并导航到Basics教程的编辑、插入和删除部分中的Basics.aspx页面(~/EditInsertDelete/Basics.aspx)。更新某产品的名称或价格。然后,从第一个浏览器窗口查看另一个不同的数据页、对网格进行排序或单击某行的Edit按钮。这次,"Selectingeventfired"又出现了,因为底层数据库数据已更改(参见图10)。如果该文本没有出现稍等后重试。我们知道,轮询服务每隔pollTime毫秒检测一次Products表的变化,因此在底层数据的更新和缓存数据的清除之间有一个延迟。(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表会清除缓存的产品数据步骤6:通过编程方式使用SqlCacheDependency类在架构中缓存数据教程讲述了在架构中使用一个单独的缓存层的好处,这胜过了缓存功能与ObjectDataSource紧密结合的情况。在那个教程中,我门创建了一个ProductsCL类来演示怎样以编程的方式进行数据缓存。要在缓存层使用SQL缓存依赖项,要使用SqlCacheDependency类。在轮询系统中,一个SqlCacheDependency对象必须与某个具体的数据库和表相关联。例如,下面的代码创建了一^基于Northwind数据库的Products表的SqlCacheDependency对象:ableDependency=NorthwindDB”,"Products");SqlCacheDependency的构造函数的两个输入参数分别是数据库名和表名。与ObjectDataSource的SqlCacheDependency属性类似,使用的数据库名是Web.config文件中<add>元素的name属性指定的值。表名是实际的数据库表名。要将一个SqlCacheDependency与一个添加到数据缓存中的条目相关联,可以使用一个接受依赖项的Insert重载方法。下面的代码将value添加到数据缓存中,缓存时间不限,并将它基于Products表的SqlCacheDependency相关联。换言之,value会一直保持在缓存中,直到由于内存不足或轮询系统检测到Products表在缓存后发生了改变才被清除。ableDependency=NorthwindDB","Products");,e.NoAbsoluteExpiration,e.NoSlidingExpiration);目前,缓存层的ProductsCL类缓存Products表的数据,基于时间的有效期为60秒。我们对该类进行更新,使其使用SQL缓存依赖项。ProductsCL类的AddCacheltem方法负责将数据添加至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}更新该代码,用一^个SqlCacheDependency对象来替换掉MasterCacheKeyArray缓存依赖项:Key,objectvalue)he=HttpRuntime.Cache;jectsforProductsctsTableDependency=cy("NorthwindDB","Products");eusingproductsTableDependencyDataCache.Insert(GetCacheKey(rawKey),value,proCaching.Cache.NoAbsoluteExpiration,Caching.}为了测试该功能,在页面已有的ProductsDeclarativeGridView下面另外添加一个GridView。将该新GridView的ID设置为ProductsProgrammatic,通过其智能标签将其绑定到一^新的名为ProductsDataSourceProgrammatic的ObjectDataSource。配置该ObjectDataSource使用ProductsCL类在SELECT和UPDATE选项卡的下拉列表中分别选择GetProducts和UpdateProduct。
图11:配置ObjectDataSource使用ProductsCL类
图12:在SELECT选项卡的下拉列表中选择GetProducts方法图13:在UPDATE选项卡的下拉列表中选择UpdateProduct方法完成ConfigureDataSource向导后,VisualStudio将为每个数据字段在GridView中创建BoundField和CheckBoxField。与添加到该页的第一^个GridView一样,将ProductName、CategoryName和UnitPrice之外的所有字段删除,并按照您的意愿格式化这些字段。在GridView的智能标签中,选中EnablePaging、EnableSorting和EnableEditing复选框。与ProductsDataSourceDeclarativeObjectDataSource一样,VisualStudio会将ProductsDataSourceProgrammaticObjectDataSource的OldValuesParameterFormatString属性设置为original_{0}。为使GridView的编辑功能正常工作,将该属性置回{0}(或从声明语句中完全地删除该属性赋值)。完成这些任务后,最终的GridView和ObjectDataSource声明代码类似如下:ic"runat="server"KeyNames="ProductID”Programmatic"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>为测试缓存层中的SQL缓存依赖项,在ProductCL类的AddCacheltem方法中设置一个断点,然后启动调试。首次访问SqlCacheDependencies.aspx时,会触发断点,因为是首次请求数据,且数据会被放入缓存中。接下来,在GridView中跳转到另一页或对某个列进行排序。这会导致GridView查询数据,由于Products数据库表尚未改动,会在缓存中找到数据。如果反复在缓存中找不到数据,确保您机器上有足够可用的内存,然后重试。在GridView里跳转几页,打开另一个浏览器窗口,导航到Basics教程的编辑、插入和删除部分中的Basics.aspx页面(~/EditInsertDelete/Basics.aspx)。更新Products表的一条记录,然后从第一个浏览器窗口查看一个新页或单击一个排序标题。此时,会遇到以下两种情况之一:要么触发断点,这意味着缓存数据由于数据库发生变化而被清除;要么不触发断点,意味着SqlCacheDependencies.aspx显示的是过时的数据。如果没有触发断点,很可能是由于数据变化后还未触发轮询服务。我们知道,轮询服务每隔pollTime毫秒检测一次Products表的变化,因此在底层数据的更新和缓存数据的清除之间有一个延迟。注意:通过SqlCacheDependencies.aspx中的GridView编辑某个产品时很可能会产生该延迟。在架构中缓存数据教程中,我们添加了MasterCacheKeyArray缓存依赖项以确保通过ProductsCL类的UpdateProduct方法编辑的数据会从缓存中清除。然而在本步骤开始时,我们在修改AddCacheItem方法时替换了该缓存依赖项,因此ProductsCL类会继续显示缓存的数据,直到轮询系统发现Products表的变化。我们将在步骤7中了解怎样重新引入MasterCacheKeyArray缓存依赖项。步骤7:将一个缓存条目与多个依赖项相关联我们知道,MasterCacheKeyArray缓存依赖项用于确保在缓存中与产品相关的所有条目中,只要其中一条的相关数据发生更改,所有与产品相关的数据都会从缓存清除。例如,GetProductsByCategorylDCategoryD)方法对每个独特的categorylD值缓存多个ProductsDataTables实例。如果其中一个对象被清除,MasterCacheKeyArray缓存依赖项会确保其它对象也被清除。如果没有该缓存依赖项,就会存在这种可能性,当缓存的数据被修改后,其它缓存的产品数据可能过时。因此,在使用SQL缓存依赖项的时候保持MasterCacheKeyArray缓存依赖项是很重要的。然而,数据缓存的Insert方法只允许一个依赖项对象。此外,在使用SQL缓存依赖项时,我们可能要依赖多个数据库表。例如,在ProductsCL类中缓存的ProductsDataTable包含每个产品的分类名称和供/
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 农场转让合同协议书模板
- 校园数字文化塑造实施路径及策略
- 养老护理培训公司创业计划书
- 2025年天然植物纤维及人造纤维编织工艺品项目可行性研究报告
- 费用补偿合同协议书模板
- 委托他人采购合同协议书
- 办卡合同协议书怎么写
- 承包分拣合同协议书模板
- 工作劳务合同协议书模板
- 培训行业创办一家职业技能培训学校的商业计划书
- 门诊部职责及管理制度(3篇)
- 安装门窗免责协议书
- 国际私法(华东政法大学)智慧树知到期末考试答案章节答案2024年华东政法大学
- QB/T 8011-2024 咸鸭蛋黄(正式版)
- 2024医疗机构重大事故隐患判定清单(试行)学习课件
- JJG 705-2014液相色谱仪行业标准
- 设备保养与维护培训
- 烫伤的护理课件
- 孔子学院教学大纲
- 协同治理:理论研究框架与分析模型
- JTS-T 200-2023 设计使用年限50年以上港口工程结构设计指南
评论
0/150
提交评论