我的老人'程序员将网格数据存储在会话变量中,以便对其进行排序。
我们每隔一天都要重启我们的服务器,因为它开始挂起。我觉得这是因为所有这些Session变量都在内存中浮动。
这是排序数据的最佳方式吗?有最好的做法吗?我们必须使用存储过程,因为这是他的规则。 Web应用程序非常慢,而且我对 SQL 的了解不足以帮助加快它的速度。
是否有关于会话变量的想法?还有更好的方法吗?
负荷数据方法
SqlConnection conn = new SqlConnection (ConfigurationManager.AppSettings ["ConnectionString"].ToString ());
SqlCommand cmd = conn.CreateCommand ();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "RandomStoredProdcedureName";
try
{
DataTable GridData = new DataTable ();
conn.Open ();
using (SqlDataAdapter Sqlda = new SqlDataAdapter (cmd))
{
Sqlda.Fill (GridData);
}
//Persist the table in the Session object. (for sorting)
Session ["GridData"] = GridData;
gvDetails.DataSource = GridData;
gvDetails.DataBind ();
}
catch (Exception ex)
{
Removed for brevity
}
finally
{
if (conn != null) {
conn.Close ();
}
}
排序方法
protected void gvDetails_Sorting (object sender, GridViewSortEventArgs e) {
//Retrieve the table from the session object.
DataTable GridData = Session ["GridData"] as DataTable;
if (GridData != null) {
//Sort the data.
GridData.DefaultView.Sort = e.SortExpression + " " + GetSortDirection (e.SortExpression);
gvDetails.DataSource = GridData;
gvDetails.DataBind ();
}
}
答案 0 :(得分:1)
用户不可能查看比网格显示的行数更多的记录 - 如果您的网格有25行,则超过25行的任何内容都会浪费内存/ CPU时间来处理。 (请记住,这些数字不是绝对的 - 某些应用程序可能需要更多行,有些可能需要更少。这还取决于用户查看数据并理解数据的程度。有些用户工作得更好一次只有几行,有些需要很多行 - 这甚至可能是用户的偏好,但最重要的是拉动一个巨大的结果集几乎总是浪费。)
您不应该在给定时间从数据库中提取更多数据,而不是可以在网格中显示的行数。排序应该在数据库中完成,因此您只能返回实际需要的行子集。这可以最大限度地减少Web服务器和数据库服务器之间的网络流量,并最大限度地减少Web服务器上的内存使用,因为您只将数据存储在实际需要的视图/会话状态中。
如果您使用视图状态来存储数据(这比使用Session
更好,因为只有当用户查看带有网格的特定页面时才存储数据),该数据将被发送浏览器 - 您还可以通过这种方式最小化Web服务器和浏览器之间的网络流量。
如果用户尝试以不同方式对数据进行排序或转向其他页面,只需重复上述过程并根据新的页面索引和/或新的排序字段获取新行。
修改强>:
我刚刚注意到你在问题中添加了一条评论,你通常有15个用户并返回50-1000行。除非您的Web服务器内存很少(或者除非数据库中的行巨大),否则它不太可能导致内存不足错误。您是否在会话变量中存储其他大型结果集?
答案 1 :(得分:0)
我认为排序可以在SQL中完成。但我们也必须看到SP。我从不在会话中保留DataTables,我不认为这是一个好方法。
如果数据太大而无法在每次开发人员需要时从数据库中获取数据,他/她就可以创建视图并从该视图中获取数据。它会快得多
答案 2 :(得分:0)
只需使用viewstate。
ViewState["GridData"] = GridData;
如果您能告诉我们Grid的大小,它也会有所帮助吗?
答案 3 :(得分:0)
我看不到DataTable的位置,你有问题。 我的建议是做这样的事情
public void GetData()
{
using(var conn = new SqlConnection (ConfigurationManager.AppSettings ["ConnectionString"].ToString ()))
{
SqlCommand cmd = conn.CreateCommand ();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "RandomStoredProdcedureName";
conn.Open ();
try {
using(var GridData = new DataTable ())
{
using (SqlDataAdapter Sqlda = new SqlDataAdapter (cmd))
{
Sqlda.Fill (GridData);
}
//Persist the table in the Session object. (for sorting)
Session ["GridData"] = CREATE_YOUR_OWN_OBJECTS_FROM_THE_DT(GridData);
}
} catch (Exception ex) {
Removed for brevity
} finally {
if (conn != null) {
conn.Close ();
}
}
}
}
当然有更好的方法可以做到这一点,然后你应该实现排序,但我敢打赌问题是IDisposable对象从来没有被处理过