我读了asp设计的最佳实践。其中一个建议是避免使用ViewState。 我已经习惯在我的应用程序中使用它,因为它使得处理信息的生活更轻松,而不需要进行太多的DB调用。特别是在使用GRids时。
但是,我在向ViewState加载20,000行时遇到了问题。在页面加载中,我执行db load
IF not isPostBack then
' load viestate with 20,000 rows from db
' bind grid to viewstate
end if
页面加载正常,所有信息都显示在网格中,没有错误。但是,当我点击任何服务器按钮时,我被重定向到一个页面,说明页面不可用 - 好像页面不存在或我丢失了互联网连接。请注意,在后面的代码中,我不会重定向到任何页面。
如果我注释掉加载视图状态或者将少于10,000行加载到Viewstate中 - 则不会发生此问题。
所以我很困惑为什么会这样。显然看起来Viewstate从来没有设计用于容纳大型数据表。
所以我想知道的是:
我应该使用什么而不是viewstate来避免数据库调用(我正在做的基本上是加载网格,然后允许用户对网格数据进行CRUD操作。一旦完成,我将数据保存到数据库并编辑Viewstate并将其重新绑定到网格 - 这是一种有效的方法。)
最好是在CRUD操作中进行更多数据库调用,还是减少数据库调用,保存和编辑页面代码中的数据表副本,并将其用于网格重新绑定,这样做更好。
答案 0 :(得分:3)
如果您尝试将20,000行数据绑定到GridView,那么无论您在何处存储数据,都会遇到困难。 ViewState
对于它来说是一个特别糟糕的地方,正如评论家所提到的:你实际上是在每次请求时将整个数据库发送给用户,但只允许他们看到少数这些行。
更合适的方法是首先更改查询数据库的方式,然后引入服务器端分页。这样,您只向用户发送实际显示在页面上的数据(10 - 100行),并且框架不会尝试代表用户缓存整个数据库(在ViewState或SessionState或其他地方)。 / p>
Scott Mitchell有一个关于这个确切问题的优秀教程系列:Tutorial 25: Efficiently Paging Through Large Amounts of Data
这是要点:
步骤1)更新数据库查询以支持分页:
SELECT PriceRank, ProductName, UnitPrice
FROM
(SELECT ProductName, UnitPrice,
ROW_NUMBER() OVER(ORDER BY UnitPrice DESC) AS PriceRank
FROM Products
) AS ProductsWithRowNumber
WHERE PriceRank > StartRowIndex AND
PriceRank <= (StartRowIndex + MaximumRows)
步骤2)引入一个返回总行数的数据库查询:
SELECT COUNT(*)
FROM Products
步骤3)连接GridView以使用这些方法并启用自动分页
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="True"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1"
AllowPaging="True" />
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetProductsPaged"
SelectCountMethod="GetTotalProducts"
TypeName="ProductsBLL">
<SelectParameters>
<asp:Parameter Name="startRowIndex" Type="Int32" />
<asp:Parameter Name="maximumRows" Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
文章系列深入探讨,我强烈建议您进行探索。