我有一个函数,每次按下按钮或每次更改 7 个 DropDownList 选择中的任何一个时都会运行查询。如何更改现有方法以使用 Session 或 ViewState,以便我的页面运行一次查询,然后针对 Session 或 ViewState 进行查询,而不是针对每个请求都转到我的 SQL 服务器?
代码隐藏:
protected void Page_Load(object sender, EventArgs e)
{
strMainQuery = @"SELECT 'http://dddfgdgdfg?objectid=' + CT.OBJECTID + '&classid=1224' 'Task Detail'
,LTRIM(RTRIM(CT.ATTR2846)) 'Service'
,LTRIM(RTRIM(CT.ATTR2812)) 'Status'
,CONVERT(VARCHAR(14), CT.ATTR2752, 110) 'Due Date'
,LTRIM(RTRIM(CT.ATTR2739)) 'Task Name'
,LTRIM(RTRIM(UA.REALNAME)) 'Owner'
,LTRIM(RTRIM(CT.ATTR2799)) 'Client'
FROM HSI.RMOBJECTINSTANCE1224 CT INNER JOIN HSI.RMOBJECTINSTANCE1232 S ON CT.ATTR2846 = S.ATTR2821 INNER JOIN HSI.USERACCOUNT UA ON S.FK2852 = (UA.USERNUM * -1)";
if (!Page.IsPostBack)
{
ViewState["sortOrder"] = "Asc";
ViewState["sortExp"] = "Due Date";
PullData("Due Date", "Asc"); //ASC: A (top) to Z (bottom) || # (low to high) || Date (oldest to newest)
}
else
{
PullData(ViewState["sortExp"].ToString(), ViewState["sortOrder"].ToString());
}
}
public void PullData(string sortExp, string sortDir)
{
string query = "";
DataTable taskData = new DataTable();
connString = ""; //connection string
if (ddlTaskName.SelectedIndex > 0)
{
strClause += " AND CT.ATTR2739 = '" + ddlTaskName.SelectedItem.Text + "'";
}
else
{
strClause += " AND CT.ATTR2739 LIKE '%'";
}
if (ddlService.SelectedIndex > 0)
{
strClause += " AND CT.ATTR2846 = '" + ddlService.SelectedItem.Text + "'";
}
else
{
strClause += " AND CT.ATTR2846 LIKE '%'";
}
if (ddlStatus.SelectedIndex > 0)
{
strClause += " AND CT.ATTR2812 = '" + ddlStatus.SelectedItem.Text + "'";
}
else
{
strClause += " AND CT.ATTR2812 LIKE '%'";
}
if (ddlDueDate.SelectedIndex > 0)
{
strClause += " AND CONVERT(VARCHAR(14), CT.ATTR2752, 110) = '" + ddlDueDate.SelectedItem.Text + "'";
}
else
{
strClause += " AND CONVERT(VARCHAR(14), CT.ATTR2752, 110) LIKE '%'";
}
if (ddlOwner.SelectedIndex > 0)
{
strClause += " AND UA.REALNAME = '" + ddlOwner.SelectedItem.Text + "'";
}
else
{
strClause += " AND UA.REALNAME LIKE '%'";
}
if (ddlClient.SelectedIndex > 0)
{
strClause += " AND CT.ATTR2799 = '" + ddlClient.SelectedItem.Text + "'";
}
else
{
strClause += " AND CT.ATTR2799 LIKE '%'";
}
if (ddlTaskName.SelectedIndex == 0 && ddlService.SelectedIndex == 0 && ddlStatus.SelectedIndex == 0 && ddlDueDate.SelectedIndex == 0 && ddlOwner.SelectedIndex == 0 && ddlClient.SelectedIndex == 0)
{
query = strMainQuery + " WHERE CT.ACTIVESTATUS = 0";
}
else
{
query = strMainQuery + " WHERE CT.ACTIVESTATUS = 0" + strClause;
}
using (SqlConnection conn = new SqlConnection(connString))
{
try
{
SqlCommand cmd = new SqlCommand(query, conn);
// create data adapter
SqlDataAdapter da = new SqlDataAdapter(query, conn);
// this will query your database and return the result to your datatable
DataSet myDataSet = new DataSet();
da.Fill(myDataSet);
DataView myDataView = new DataView();
myDataView = myDataSet.Tables[0].DefaultView;
if (sortExp != string.Empty)
{
//MessageBox.Show(sortExp);
//MessageBox.Show(sortDir);
myDataView.Sort = string.Format("{0} {1}", sortExp, sortDir);
}
yourTasksGV.DataSource = myDataView;
yourTasksGV.DataBind();
TasksUpdatePanel.Update();
conn.Close();
}
catch (Exception ex)
{
string error = ex.Message;
}
}
}
如您所见,每次调用 PullData
时,它都会转到 SQL 服务器并运行查询,一旦我开始拥有越来越多的数据,它最终会变慢。
如何将现有方法转换为查询一次并保存到 Session/ViewState,这样我就不必每次都对 SQL Server 进行查询?
在运行查询之前,检查缓存。如果它在那里,请使用它。如果没有,运行查询并将结果数据添加到缓存中。
你可以使用 Cache.Insert Method (String, Object, CacheDependency, DateTime, TimeSpan) .您可以找到一些很棒的缓存技巧:ASP.NET Caching: Techniques and Best Practices .
以下是我构建 PullData 方法的方式:
public void PullData(string sortExp, string sortDir)
{
// build your query string
// ...
// Now create a hash of that query string
string cacheKey = HashHelper(query);
DataSet ds = null;
// check cache if key exists
if(Cache[cacheKey] != null)
{
// read dataset from cache
ds = (DataSet)Cache[cacheKey];
}
else
{
// perform sql command and fill your dataset
// ....
// save dataset to cache for 30 minutes or whatever you like
Cache.Insert(cacheKey, ds, null, DateTime.Now.AddMinutes(30), TimeSpan.Zero);
}
// Get DataView based on sort options
DataView myDataView = new DataView();
myDataView = ds.Tables[0].DefaultView;
if (sortExp != string.Empty)
{
myDataView.Sort = string.Format("{0} {1}", sortExp, sortDir);
}
yourTasksGV.DataSource = myDataView;
yourTasksGV.DataBind();
TasksUpdatePanel.Update();
// keep calm and carry on
}
这是我的哈希助手
private string HashHelper(string query)
{
using (SHA256Managed hashEngine = new SHA256Managed())
{
byte[] data = hashEngine.ComputeHash(Encoding.UTF8.GetBytes(query));
StringBuilder hash = new StringBuilder(64);
for (int i = 0; i < data.Length; i++)
{
hash.Append(data[i].ToString("x2"));
}
return hash.ToString();
}
}
我是一名优秀的程序员,十分优秀!