将视图状态存入数据库(2)

前几天我写一篇将视图状态存入数据库(.net 2.0),感觉有写不妥,今天我重新整理了一下,性能上比原来要好很多。
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, 010);
                
//从al中移除前10条元素
                list.RemoveRange(010);

                
//循环遍历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即可。
posted @ 2008-05-04 12:50  王庆  阅读(635)  评论(4编辑  收藏  举报