将视图状态存入数据库(2)
前几天我写一篇将视图状态存入数据库(.net 2.0),感觉有写不妥,今天我重新整理了一下,性能上比原来要好很多。
代码中都有注释,不难理解,如果还有不清楚的地方,给我留言,我会尽快给各位回复。
有几点说明一下:
DataAccess是一个数据库访问类,我没有提供相应的代码,你可以替换成你自己的。
使用的时候,你只需用BasePage替换掉页面的System.Web.UI.Page即可。
using System;
using System.Web.UI;
using System.IO;
using ICSharpCode.SharpZipLib.Zip.Compression;
using System.Collections;
using JianCaiWeb.DbAccess;
using System.Text;
using System.Collections.Generic;
namespace JianCaiWeb.Utils
{
/**/
/// <summary>
/// PageClass 的摘要说明。
/// </summary>
public class BasePage : System.Web.UI.Page
{
protected override PageStatePersister PageStatePersister
{
get
{
return new DatabasePageStatePersister(this);
}
}
}
public class DatabasePageStatePersister : PageStatePersister
{
private static DataAccess da;
private static List<DictionaryEntry> list = new List<DictionaryEntry>();
public DatabasePageStatePersister(Page page)
: base(page)
{
da = DataAccessFactory.CreateDataAccess();
}
//载入控件状态
public override void Load()
{
string stateID = base.Page.Request["__VIEWSTATE_KEY"].ToString();
string viewState = this.LoadViewState(stateID);
IStateFormatter formatter = this.StateFormatter;
Pair statePair = (Pair)formatter.Deserialize(viewState);
this.ViewState = statePair.First;
this.ControlState = statePair.Second;
}
// 保存控件状态
public override void Save()
{
if (this.ViewState != null || this.ControlState != null)
{
Guid guid = Guid.NewGuid();
string viewStateID = guid.ToString();
base.Page.ClientScript.RegisterHiddenField("__VIEWSTATE_KEY", viewStateID);
Pair statePair = new Pair(ViewState, ControlState);
IStateFormatter formatter = this.StateFormatter;
string serializedState = formatter.Serialize(statePair);
this.SaveViewState(viewStateID, serializedState);
}
}
//保存ViewState
private void SaveViewState(string viewStateID,string viewState)
{
DictionaryEntry newEntry = new DictionaryEntry();
newEntry.Key = viewStateID;
newEntry.Value = viewState;
list.Add(newEntry);
//当al中的元素数量大于等于1000时,将其前10条放入数据库
if (list.Count >= 1000)
{
//声明一数组,用于存放al的前10条元素
DictionaryEntry[] entryArray = new DictionaryEntry[10];
//al的前10条元素拷贝至objs数组中
list.CopyTo(0, entryArray, 0, 10);
//从al中移除前10条元素
list.RemoveRange(0, 10);
//循环遍历objs,将其所包含的元素存入数据库中
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10; i++)
{
DictionaryEntry oldEntry = entryArray[i];
sb.Append(string.Format("insert into ViewState (viewStateID,ViewState) values ('{0}','{1}');", oldEntry.Key, oldEntry.Value));
}
da.ExecuteNonQuery(sb.ToString());
}
}
//读取ViewState
private string LoadViewState(string viewStateID)
{
string viewState = string.Empty;
//遍历al,如果匹配到相应的ViewState,则从al中移除该元素
foreach (DictionaryEntry entry in list)
{
if (entry.Key.ToString() == viewStateID)
{
viewState = entry.Value.ToString();
list.Remove(entry);
break;
}
}
//在al中没有匹配到相应的ViewState,则从数据库中读取
if (viewState == null)
{
string strSql = "select viewState from viewState where viewStateID = '" + viewStateID + "'";
viewState = da.ExecuteScalar(strSql).ToString();
}
return viewState;
}
}
}
using System.Web.UI;
using System.IO;
using ICSharpCode.SharpZipLib.Zip.Compression;
using System.Collections;
using JianCaiWeb.DbAccess;
using System.Text;
using System.Collections.Generic;
namespace JianCaiWeb.Utils
{
/**/
/// <summary>
/// PageClass 的摘要说明。
/// </summary>
public class BasePage : System.Web.UI.Page
{
protected override PageStatePersister PageStatePersister
{
get
{
return new DatabasePageStatePersister(this);
}
}
}
public class DatabasePageStatePersister : PageStatePersister
{
private static DataAccess da;
private static List<DictionaryEntry> list = new List<DictionaryEntry>();
public DatabasePageStatePersister(Page page)
: base(page)
{
da = DataAccessFactory.CreateDataAccess();
}
//载入控件状态
public override void Load()
{
string stateID = base.Page.Request["__VIEWSTATE_KEY"].ToString();
string viewState = this.LoadViewState(stateID);
IStateFormatter formatter = this.StateFormatter;
Pair statePair = (Pair)formatter.Deserialize(viewState);
this.ViewState = statePair.First;
this.ControlState = statePair.Second;
}
// 保存控件状态
public override void Save()
{
if (this.ViewState != null || this.ControlState != null)
{
Guid guid = Guid.NewGuid();
string viewStateID = guid.ToString();
base.Page.ClientScript.RegisterHiddenField("__VIEWSTATE_KEY", viewStateID);
Pair statePair = new Pair(ViewState, ControlState);
IStateFormatter formatter = this.StateFormatter;
string serializedState = formatter.Serialize(statePair);
this.SaveViewState(viewStateID, serializedState);
}
}
//保存ViewState
private void SaveViewState(string viewStateID,string viewState)
{
DictionaryEntry newEntry = new DictionaryEntry();
newEntry.Key = viewStateID;
newEntry.Value = viewState;
list.Add(newEntry);
//当al中的元素数量大于等于1000时,将其前10条放入数据库
if (list.Count >= 1000)
{
//声明一数组,用于存放al的前10条元素
DictionaryEntry[] entryArray = new DictionaryEntry[10];
//al的前10条元素拷贝至objs数组中
list.CopyTo(0, entryArray, 0, 10);
//从al中移除前10条元素
list.RemoveRange(0, 10);
//循环遍历objs,将其所包含的元素存入数据库中
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10; i++)
{
DictionaryEntry oldEntry = entryArray[i];
sb.Append(string.Format("insert into ViewState (viewStateID,ViewState) values ('{0}','{1}');", oldEntry.Key, oldEntry.Value));
}
da.ExecuteNonQuery(sb.ToString());
}
}
//读取ViewState
private string LoadViewState(string viewStateID)
{
string viewState = string.Empty;
//遍历al,如果匹配到相应的ViewState,则从al中移除该元素
foreach (DictionaryEntry entry in list)
{
if (entry.Key.ToString() == viewStateID)
{
viewState = entry.Value.ToString();
list.Remove(entry);
break;
}
}
//在al中没有匹配到相应的ViewState,则从数据库中读取
if (viewState == null)
{
string strSql = "select viewState from viewState where viewStateID = '" + viewStateID + "'";
viewState = da.ExecuteScalar(strSql).ToString();
}
return viewState;
}
}
}
代码中都有注释,不难理解,如果还有不清楚的地方,给我留言,我会尽快给各位回复。
有几点说明一下:
DataAccess是一个数据库访问类,我没有提供相应的代码,你可以替换成你自己的。
使用的时候,你只需用BasePage替换掉页面的System.Web.UI.Page即可。