一个性能良好的系统,数据的读、写、查、删、改效率至关重要,其中读和查更是重中之重,本篇将以一个简单的实例来探索与数据库无关的数据静态缓存技术。所谓与数据库无关,就是无论存储数据库是何种类型,这个缓存技术都是适用的,要实现这样的数据库无关性,我们需要在数据访问层动刀,及将数据访问层进一步细分为数据库访问中间件层-数据缓存层-数据访问层,其中:
数据库访问中间件层负责与物理数据库打交道,包括物理数据的增、删、改、查等;
数据缓存层负责与数据库访问中间件层打交道,负责将中间件读取的数据缓存到内存中并实时同步数据库的增、删、改操作;
数据访问层负责与数据缓存层打交道,业务逻辑层通过数据访问层公开的方法实现数据的增、删、改、查。数据访问层只与数据库访问中间件层和数据缓存层打交道,不与物理数据库打交道,查询数据时直接访问数据缓存层,增、删、改操作首先访问数据库访问中间件层,然后调用缓存层的同步方法同步操作。
通过这样的分层方式很好的避开了各种不同的数据库缓存机制的不同而导致的开发量增加,如将数据库由MSQQLSERVER换为ACCESS,我们只需要动数据库访问中间件即可实现数据库的更改。同时,查询数据时,业务逻辑层首先在内存中查找,如果查询到直接返回查询结果,如果未查询到则将直接查询物理数据库并将查询到得结果缓存至内存,这样后续查询的时候就不需要与数据库交互了,直接由内存中查出并返回查询结果,其性能是不言而喻的。数据缓存同步机制也很重要,当物理数据库中数据发生改变时,内存中的数据应能实时或异步同步物理数据库,最简单的就是重新载入缓存,这在数据更新频率不高的系统这还可以应用,但如在数据更新频率过高的系统中显然就不适用了,因此建议在内存中直接进行数据同步而非重新载入缓存。
下面给出一个简单的实例,该实例的数据库访问中间件采用的是AppFramework,AppFramework很好的屏蔽了底层数据库的差异,更改数据库更加容易,同时引入了<ObjectTable>泛型技术。开发语言是C#2.0版本,简单的修改即可移植到其他语言中。 该实例是我开发的一个网站管理系统时写的,因数据量不是很多,所以在GetObject类中没有采用二分查找算法,而是直接采用了顺序查找,如果应用于教大量数据中,这里采用二分查找算法或其他算法效率会更高!
CacheBase.cs
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Reflection;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Diagnostics;
using System.Collections.Generic;
using System.Configuration;
namespace Live.Util
{
/// <summary>
/// 缓存基础对象
/// </summary>
public class CacheBaseObject
{
/// <summary>
/// 缓存字典的HashTable
/// </summary>
protected static Hashtable hashTableCache = new Hashtable();
/// <summary>
/// 定义缓存同步出错时处理方式
/// false为直接抛出异常,true为不抛出异常,重新载入缓存以达到同步的效果
/// </summary>
protected static bool cacheExceptionHandle = Convert.ToBoolean(ConfigurationManager.AppSettings["cacheExceptionHandle"]);
/// <summary>
/// 禁用项是否可见
/// </summary>
protected static bool isShowDisabled = Convert.ToBoolean(ConfigurationManager.AppSettings["isShowDisabled"]);
/// <summary>
/// 测试HashTableCache中指定的字典型Key是否存在
/// </summary>
/// <param name="_CategoryKey">键值</param>
public static bool TestHashTableCategoryKey(string _CategoryKey)
{
bool isExit = false;
if (_CategoryKey != "Category")
{
_CategoryKey = "Category_" + _CategoryKey;
}
if (hashTableCache == null)
{
hashTableCache = new Hashtable();
}
if (hashTableCache[_CategoryKey] != null)
{
isExit = true;
}
return isExit;
}
/// <summary>
/// 测试HashTableCache中指定的Key是否存在
/// </summary>
/// <param name="_Key">键值</param>
public static bool TestHashTableKey(string _Key)
{
bool isExit = false;
if (hashTableCache == null)
{
hashTableCache = new Hashtable();
}
if (hashTableCache[_Key] != null)
{
isExit = true;
}
return isExit;
}
}
}
CategoryHelper.cs
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using UNLV.IAP.WebControls;
using Live.BizTable.Access.Interface;
using Live.BizTable.Model;
using AppFramework.Data;
using AppFramework.DBAccess;
namespace Live.Util
{
/// <summary>
/// 有关字典的操作
/// </summary>
public class CategoryHelper : CacheBaseObject
{
/// <summary>
/// 将字典缓存至HashTable以便快速调用
/// </summary>
public static void Cache()
{
//判断是否使用缓存
if (!Convert.ToBoolean(ConfigurationManager.AppSettings[Enum_CacheItem.字典_Category]))
{
return;
}
try
{
#region 获取所有字典存入ObjectTable<Category>并缓存至HashTable
ICategoryDAO dao = DAOManager.Default.GetDAO<ICategoryDAO>();
ObjectTable<Category> lists = new ObjectTable<Category>();
QueryFilter filter = new QueryFilter();
if (!isShowDisabled)
{
filter.Items.Add(new DBField("status", DataType.String, DBOperator.Equal, "0"));
}
using (IDBSession session = DBSessionManager.Default.GetSession())
{
lists = dao.SelectList(session, "*", filter, "developlevel asc,orderindex asc,addtime desc");
}
if (TestHashTableCategoryKey("Category"))
{
hashTableCache.Remove("Category");
}
hashTableCache.Add("Category", lists);
#endregion
#region 将字典载入_HashTable
ICategoryvalueDAO valuedao = DAOManager.Default.GetDAO<ICategoryvalueDAO>();
ObjectTable<Categoryvalue> valuelists = new ObjectTable<Categoryvalue>();
QueryFilter valuefilter;
using (IDBSession session = DBSessionManager.Default.GetSession())
{
for (int i = 0; i < lists.Count; i++)
{
valuefilter = new QueryFilter();
if (!isShowDisabled)
{
valuefilter.Items.Add(new DBField("status", DataType.String, DBOperator.Equal, "0"));
}
valuefilter.Items.Add(new DBField("categoryid", DataType.String, DBOperator.Equal, lists[i].ID.Value));
valuelists = valuedao.SelectList(session, "*", valuefilter, "orderindex desc,addtime asc");
if (TestHashTableCategoryKey(lists[i].Englishname.Value))
{
hashTableCache.Remove("Category_" + lists[i].Englishname.Value);
}
hashTableCache.Add("Category_" + lists[i].Englishname.Value, valuelists);
}
}
#endregion
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// 快速获取字典中相关对象的方法
/// </summary>
public class GetObject
{
/// <summary>
/// 根据字典值获取一个字典Item对象
/// </summary>
/// <param name="_CategoryValue">字典值</param>
/// <param name="_CategoryName">字典名</param>
/// <returns></returns>
public static Categoryvalue GetCategoryValueItemByExtValue(string _CategoryValue, string _CategoryName)
{
Categoryvalue valueitem = null;
ObjectTable<Categoryvalue> valuelists = GetCategoryValueCollection(_CategoryName);
for (int i = 0; i < valuelists.Count; i++)
{
if (valuelists[i].Extvalue.Value == _CategoryValue)
{
valueitem = valuelists[i];
break;
}
}
return valueitem;
}
/// <summary>
/// 根据字典值获取一个字典Item对象
/// </summary>
/// <param name="_ID">字典项ID</param>
/// <param name="_CategoryName">字典名</param>
/// <returns></returns>
public static Categoryvalue GetCategoryValueItemByID(string _ID, string _CategoryName)
{
Categoryvalue valueitem = null;
ObjectTable<Categoryvalue> valuelists = GetCategoryValueCollection(_CategoryName);
for (int i = 0; i < valuelists.Count; i++)
{
if (valuelists[i].ID.Value == _ID)
{
valueitem = valuelists[i];
break;
}
}
return valueitem;
}
/// <summary>
/// 根据字典值获取字典名
/// </summary>
/// <param name="_CategoryValue">字典值(Extvalue)</param>
/// <param name="_CategoryValueCollection">字典值集合</param>
/// <returns></returns>
public static string GetCategoryValueNameByCategoryValue(string _CategoryValue, ObjectTable<Categoryvalue> _CategoryValueCollection)
{
string valuename = "";
for (int i = 0; i < _CategoryValueCollection.Count; i++)
{
if (_CategoryValueCollection[i].Extvalue.Value == _CategoryValue)
{
valuename = _CategoryValueCollection[i].Name.Value;
break;
}
}
if (valuename == "禁用")
{
valuename = "<font color=red>" + valuename + "</font>";
}
return valuename;
}
/// <summary>
/// 根据字典名获取字典项集合
/// </summary>
/// <param name="_CategoryName">字典名</param>
/// <returns></returns>
public static ObjectTable<Categoryvalue> GetCategoryValueCollection(string _CategoryName)
{
if (Convert.ToBoolean(ConfigurationManager.AppSettings[Enum_CacheItem.字典_Category]))
{
if (!TestHashTableCategoryKey(_CategoryName))
{
Cache();
}
return (ObjectTable<Categoryvalue>)hashTableCache["Category_" + _CategoryName];
}
else
{
try
{
ICategoryDAO dao = DAOManager.Default.GetDAO<ICategoryDAO>();
ObjectTable<Category> lists = new ObjectTable<Category>();
QueryFilter filter = new QueryFilter();
filter.Items.Add(new DBField("status", DataType.String, DBOperator.Equal, "0"));
filter.Items.Add(new DBField("englishname", DataType.String, DBOperator.Equal, _CategoryName));
using (IDBSession session = DBSessionManager.Default.GetSession())
{
lists = dao.SelectList(session, "*", filter, null);
ICategoryvalueDAO valuedao = DAOManager.Default.GetDAO<ICategoryvalueDAO>();
QueryFilter valuefilter = new QueryFilter();
valuefilter.Items.Add(new DBField("status", DataType.String, DBOperator.Equal, "0"));
valuefilter.Items.Add(new DBField("categoryid", DataType.String, DBOperator.Equal, lists[0].ID.ToString()));
return valuedao.SelectList(session, "*", valuefilter, "orderindex desc,addtime asc");
}
}
catch (Exception ex)
{
throw ex;
}
}
}
/// <summary>
/// 获取字典对象集合
/// </summary>
/// <returns></returns>
public static ObjectTable<Category> GetCategoryCollection()
{
ObjectTable<Category> lists = new ObjectTable<Category>();
if (Convert.ToBoolean(ConfigurationManager.AppSettings[Enum_CacheItem.字典_Category]))
{
if (!TestHashTableCategoryKey("Category"))
{
Cache();
}
lists = (ObjectTable<Category>)hashTableCache["Category"];
}
else
{
try
{
ICategoryDAO dao = DAOManager.Default.GetDAO<ICategoryDAO>();
QueryFilter filter = new QueryFilter();
if (!isShowDisabled)
{
filter.Items.Add(new DBField("status", DataType.String, DBOperator.Equal, "0"));
}
using (IDBSession session = DBSessionManager.Default.GetSession())
{
lists = dao.SelectList(session, "*", filter, "dlevel asc,orderindex asc,addtime desc");
}
}
catch (Exception ex)
{
throw ex;
}
}
return lists;
}
/// <summary>
/// 获取字典对象集合
/// </summary>
/// <param name="_DevelopLevel">开发级别</param>
/// <returns></returns>
public static ObjectTable<Category> GetCategoryCollection(string _DevelopLevel)
{
ObjectTable<Category> lists = GetCategoryCollection();
ObjectTable<Category> newlists = new ObjectTable<Category>();
if (_DevelopLevel != "")
{
for (int i = 0; i < lists.Count; i++)
{
if (lists[i].Developlevel.Value == _DevelopLevel)
{
newlists.Add(lists[i]);
}
}
}
else
{
newlists = lists;
}
return newlists;
}
/// <summary>
/// 根据字典ID获取一个字典Item对象
/// </summary>
/// <param name="_ID"></param>
/// <returns></returns>
public static Category GetCategoryItemByID(string _ID)
{
ObjectTable<Category> lists = GetCategoryCollection();
Category item = null;
for (int i = 0; i < lists.Count; i++)
{
if (lists[i].ID.Value == _ID)
{
item = lists[i];
break;
}
}
return item;
}
}
/// <summary>
/// 缓存同步
/// </summary>
public class CacheSynchronize
{
/// <summary>
/// Category缓存同步-Insert
/// </summary>
/// <param name="_Category">要插入的字典对象</param>
public static void Insert(ICategoryParam _Category)
{
if (!Convert.ToBoolean(ConfigurationManager.AppSettings[Enum_CacheItem.字典_Category]))
{
return;
}
if (!TestHashTableCategoryKey(_Category.Englishname.Value))
{
Cache();
return;
}
Category newitem = new Category();
string[] setFileds = newitem.GetFieldNames();
string[] getFlieds = _Category.GetFieldNames();
if (setFileds != getFlieds)
{
if (!cacheExceptionHandle)
{
throw (new Exception("传入的对象数据结构与Category结构不一致,缓存同步操作不能继续,您可以通过重载缓存来跳过缓存同步操作!"));
}
else
{
Cache();
return;
}
}
try
{
for (int i = 0; i < setFileds.Length; i++)
{
newitem.SetPropertyValueByFieldName(setFileds[i], _Category.GetPropertyByFieldName(getFlieds[i]).Value);
}
if (TestHashTableCategoryKey("Category"))
{
hashTableCache.Remove("Category");
}
((ObjectTable<Category>)hashTableCache["Category"]).Add(newitem);
if (TestHashTableCategoryKey(newitem.Englishname.Value))
{
hashTableCache.Remove("Category" + newitem.Englishname.Value);
}
hashTableCache.Add("Category" + newitem.Englishname.Value, new ObjectTable<Categoryvalue>());
}
catch (Exception ex)
{
if (!cacheExceptionHandle)
{
throw ex;
}
else
{
Cache();
}
}
}
/// <summary>
/// Category缓存同步-Delete
/// </summary>
/// <param name="_CategoryName">字典名</param>
public static void Delete(string _CategoryName)
{
if (!Convert.ToBoolean(ConfigurationManager.AppSettings[Enum_CacheItem.字典_Category]))
{
return;
}
if (!TestHashTableCategoryKey(_CategoryName))
{
Cache();
return;
}
try
{
hashTableCache.Remove("Category" + _CategoryName);
bool isExit = false;
for (int i = 0; i < ((ObjectTable<Category>)hashTableCache["Category"]).Count; i++)
{
if (((ObjectTable<Category>)hashTableCache["Category"])[i].Englishname.Value == _CategoryName)
{
((ObjectTable<Category>)hashTableCache["Category"]).Remove(((ObjectTable<Category>)hashTableCache["Category"])[i]);
isExit = true;
break;
}
}
//如未查询到要删除的记录则认为HashTable已经在其他地方被修改,数据已经不能同步,需要重新载入字典缓存
if (!isExit)
{
Cache();
}
}
catch (Exception ex)
{
if (!cacheExceptionHandle)
{
throw ex;
}
else
{
Cache();
}
}
}
/// <summary>
/// Category缓存同步-Update
/// </summary>
/// <param name="_Category">要更新的ICategoryParam对象</param>
public static void Update(ICategoryParam _Category)
{
if (!Convert.ToBoolean(ConfigurationManager.AppSettings[Enum_CacheItem.字典_Category]))
{
return;
}
if (!TestHashTableCategoryKey(_Category.Englishname.Value))
{
Cache();
return;
}
Category newitem = new Category();
string[] setFileds = newitem.GetFieldNames();
string[] getFlieds = _Category.GetFieldNames();
if (setFileds != getFlieds)
{
if (!cacheExceptionHandle)
{
throw (new Exception("传入的对象数据结构与Category结构不一致,缓存同步操作不能继续,您可以通过重载缓存来跳过缓存同步操作!"));
}
else
{
Cache();
return;
}
}
bool isExit = false;
try
{
for (int i = 0; i < ((ObjectTable<Category>)hashTableCache["Category"]).Count; i++)
{
if (((ObjectTable<Category>)hashTableCache["Category"])[i].ID.Value == _Category.ID.Value)
{
for (int j = 1; j < getFlieds.Length; j++)
{
if (_Category.GetPropertyByFieldName(getFlieds[j]).Value == null)
{
continue;
}
((ObjectTable<Category>)hashTableCache["Category"])[i].SetPropertyValueByFieldName(getFlieds[j], _Category.GetPropertyByFieldName(getFlieds[j]).Value);
}
isExit = true;
break;
}
}
//如未查询到要删除的记录则认为HashTable已经在其他地方被修改,数据已经不能同步,需要重新载入字典缓存
if (!isExit)
{
Cache();
}
}
catch (Exception ex)
{
if (!cacheExceptionHandle)
{
throw ex;
}
else
{
Cache();
}
}
}
/// <summary>
/// CategoryValue缓存同步-Insert
/// </summary>
/// <param name="_CategoryValue">要插入的ICategoryvalueParam对象</param>
/// <param name="_CategoryName">字典名</param>
public static void Insert(ICategoryvalueParam _CategoryValue, string _CategoryName)
{
if (!Convert.ToBoolean(ConfigurationManager.AppSettings[Enum_CacheItem.字典_Category]))
{
return;
}
if (!TestHashTableCategoryKey(_CategoryName))
{
Cache();
return;
}
Categoryvalue newvalueitem = new Categoryvalue();
string[] setFileds = newvalueitem.GetFieldNames();
string[] getFlieds = _CategoryValue.GetFieldNames();
if (setFileds != getFlieds)
{
if (!cacheExceptionHandle)
{
throw (new Exception("传入的对象数据结构与Category结构不一致,缓存同步操作不能继续,您可以通过重载缓存来跳过缓存同步操作!"));
}
else
{
Cache();
return;
}
}
try
{
for (int i = 0; i < setFileds.Length; i++)
{
newvalueitem.SetPropertyValueByFieldName(setFileds[i], _CategoryValue.GetPropertyByFieldName(getFlieds[i]).Value);
}
((ObjectTable<Categoryvalue>)hashTableCache["Category" + _CategoryName]).Add(newvalueitem);
}
catch (Exception ex)
{
if (!cacheExceptionHandle)
{
throw ex;
}
else
{
Cache();
}
}
}
/// <summary>
/// CategoryValue缓存同步-Delete
/// </summary>
/// <param name="_CategoryValueID">要删除的字典项的CategoryID</param>
/// <param name="_CategoryName">字典名</param>
public static void Delete(string _CategoryValueID, string _CategoryName)
{
if (!Convert.ToBoolean(ConfigurationManager.AppSettings[Enum_CacheItem.字典_Category]))
{
return;
}
if (!TestHashTableCategoryKey(_CategoryName))
{
Cache();
return;
}
try
{
bool isExit = false;
for (int i = 0; i < ((ObjectTable<Categoryvalue>)hashTableCache["Category" + _CategoryName]).Count; i++)
{
if (((ObjectTable<Categoryvalue>)hashTableCache["Category" + _CategoryName])[i].Categoryid.Value == _CategoryValueID)
{
((ObjectTable<Categoryvalue>)hashTableCache["Category" + _CategoryName]).Remove(((ObjectTable<Categoryvalue>)hashTableCache["Category" + _CategoryName])[i]);
isExit = true;
break;
}
}
//如未查询到要删除的记录则认为HashTable已经在其他地方被修改,数据已经不能同步,需要重新载入字典缓存
if (!isExit)
{
Cache();
}
}
catch (Exception ex)
{
if (!cacheExceptionHandle)
{
throw ex;
}
else
{
Cache();
}
}
}
/// <summary>
/// CategoryValue缓存同步-Update
/// </summary>
/// <param name="_CategoryValue">要更新的ICategoryvalueParam对象</param>
/// <param name="_CategoryName">字典名</param>
public static void Update(ICategoryvalueParam _CategoryValue, string _CategoryName)
{
if (!Convert.ToBoolean(ConfigurationManager.AppSettings[Enum_CacheItem.字典_Category]))
{
return;
}
if (!TestHashTableCategoryKey(_CategoryName))
{
Cache();
return;
}
Category newitem = new Category();
string[] setFileds = newitem.GetFieldNames();
string[] getFlieds = _CategoryValue.GetFieldNames();
if (setFileds != getFlieds)
{
if (!cacheExceptionHandle)
{
throw (new Exception("传入的对象数据结构与Category结构不一致,缓存同步操作不能继续,您可以通过重载缓存来跳过缓存同步操作!"));
}
else
{
Cache();
return;
}
}
bool isExit = false;
try
{
for (int i = 0; i < ((ObjectTable<Categoryvalue>)hashTableCache["Category" + _CategoryName]).Count; i++)
{
if (((ObjectTable<Categoryvalue>)hashTableCache["Category" + _CategoryName])[i].ID.Value == _CategoryValue.ID.Value)
{
for (int j = 1; j < getFlieds.Length; j++)
{
if (_CategoryValue.GetPropertyByFieldName(getFlieds[j]).Value == null)
{
continue;
}
((ObjectTable<Categoryvalue>)hashTableCache["Category" + _CategoryName])[i].SetPropertyValueByFieldName(getFlieds[j], _CategoryValue.GetPropertyByFieldName(getFlieds[j]).Value);
}
isExit = true;
break;
}
}
//如未查询到要删除的记录则认为HashTable已经在其他地方被修改,数据已经不能同步,需要重新载入字典缓存
if (!isExit)
{
Cache();
}
}
catch (Exception ex)
{
if (!cacheExceptionHandle)
{
throw ex;
}
else
{
Cache();
}
}
}
}
#region 数据绑定至控件
/// <summary>
/// 将字典绑定至控件
/// </summary>
/// <param name="_DropDownList">DropDownList控件</param>
/// <param name="_CategoryName">字典名</param>
/// <param name="_DataTextField">绑定到DropDownList的文本字段,Enum_CategoryValueFileds枚举值之一</param>
/// <param name="_DataValueField">绑定到DropDownList的值字段,Enum_CategoryValueFileds枚举值之一</param>
public static void DataBind(DropDownList _DropDownList, string _CategoryName, string _DataTextField, string _DataValueField)
{
_DropDownList.DataSource = GetObject.GetCategoryValueCollection(_CategoryName);
_DropDownList.DataValueField = _DataValueField;
_DropDownList.DataTextField = _DataTextField;
_DropDownList.DataBind();
}
/// <summary>
/// 将字典绑定至控件
/// </summary>
/// <param name="_DropDownList">DropDownList控件</param>
/// <param name="_CategoryName">字典名</param>
/// <param name="_DataTextField">绑定到DropDownList的文本字段,Enum_CategoryValueFileds枚举值之一</param>
/// <param name="_DataValueField">绑定到DropDownList的值字段,Enum_CategoryValueFileds枚举值之一</param>
/// <param name="_AppendFiledText">附加选项文本</param>
/// <param name="_AppendFiledValue">附加选项值</param>
public static void DataBind(DropDownList _DropDownList, string _CategoryName, string _DataTextField, string _DataValueField, string _AppendFiledText, string _AppendFiledValue)
{
_DropDownList.DataSource = GetObject.GetCategoryValueCollection(_CategoryName);
_DropDownList.DataValueField = _DataValueField;
_DropDownList.DataTextField = _DataTextField;
_DropDownList.DataBind();
_DropDownList.Items.Insert(0, new ListItem(_AppendFiledText, _AppendFiledValue));
}
/// <summary>
/// 将字典绑定至控件
/// </summary>
/// <param name="_HtmlSelect">HtmlSelect控件</param>
/// <param name="_CategoryName">字典名</param>
/// <param name="_DataTextField">绑定到HtmlSelect的文本字段,Enum_CategoryValueFileds枚举值之一</param>
/// <param name="_DataValueField">绑定到HtmlSelect的值字段,Enum_CategoryValueFileds枚举值之一</param>
public static void DataBind(HtmlSelect _HtmlSelect, string _CategoryName, string _DataTextField, string _DataValueField)
{
_HtmlSelect.DataSource = GetObject.GetCategoryValueCollection(_CategoryName);
_HtmlSelect.DataValueField = _DataValueField;
_HtmlSelect.DataTextField = _DataTextField;
_HtmlSelect.DataBind();
}
/// <summary>
/// 将字典绑定至控件
/// </summary>
/// <param name="_HtmlSelect">HtmlSelect控件</param>
/// <param name="_CategoryName">字典名</param>
/// <param name="_DataTextField">绑定到HtmlSelect的文本字段,Enum_CategoryValueFileds枚举值之一</param>
/// <param name="_DataValueField">绑定到HtmlSelect的值字段,Enum_CategoryValueFileds枚举值之一</param>
/// <param name="_AppendFiledText">附加选项文本</param>
/// <param name="_AppendFiledValue">附加选项值</param>
public static void DataBind(HtmlSelect _HtmlSelect, string _CategoryName, string _DataTextField, string _DataValueField, string _AppendFiledText, string _AppendFiledValue)
{
_HtmlSelect.DataSource = GetObject.GetCategoryValueCollection(_CategoryName);
_HtmlSelect.DataValueField = _DataValueField;
_HtmlSelect.DataTextField = _DataTextField;
_HtmlSelect.DataBind();
_HtmlSelect.Items.Insert(0, new ListItem(_AppendFiledText, _AppendFiledValue));
}
/// <summary>
/// 将字典绑定至控件
/// </summary>
/// <param name="_DropDownCheckList">DropDownCheckList控件</param>
/// <param name="_CategoryName">字典名</param>
/// <param name="_DataTextField">绑定到DropDownCheckList的文本字段,Enum_CategoryValueFileds枚举值之一</param>
/// <param name="_DataValueField">绑定到DropDownCheckList的值字段,Enum_CategoryValueFileds枚举值之一</param>
public static void DataBind(DropDownCheckList _DropDownCheckList, string _CategoryName, string _DataTextField, string _DataValueField)
{
_DropDownCheckList.DataTextField = _DataTextField;
_DropDownCheckList.DataValueField = _DataValueField;
_DropDownCheckList.DataSource = GetObject.GetCategoryValueCollection(_CategoryName);
_DropDownCheckList.DataBind();
}
#endregion
}
}
一个带二次缓存结果集的范例:
ProductHelper.cs
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using UNLV.IAP.WebControls;
using Live.BizTable.Access.Interface;
using Live.BizTable.Model;
using AppFramework.Data;
using AppFramework.DBAccess;
namespace Live.Util
{
/// <summary>
/// 编辑时用
/// </summary>
public class ProductHelper : CacheBaseObject
{
/// <summary>
/// 将内容缓存至HashTable以便快速调用
/// </summary>
public static void Cache(string _DocumentID)
{
string workSpaceID = Common.GetEditWorkSpaceID();
//提供跨工作区调用数据源支持
workSpaceID = SiteHelper.GetObject.GetItem(workSpaceID).Datasource.Value;
//判断是否使用缓存
if (!Convert.ToBoolean(ConfigurationManager.AppSettings[Enum_CacheItem.产品_Product]))
{
return;
}
try
{
#region 获取所有内容存入ObjectTable<Product>并缓存至HashTable
IProductDAO dao = DAOManager.Default.GetDAO<IProductDAO>();
ObjectTable<Product> lists = new ObjectTable<Product>();
QueryFilter filter = new QueryFilter();
if (!isShowDisabled)
{
filter.Items.Add(new DBField("status", DataType.String, DBOperator.Equal, "0"));
}
filter.Items.Add(new DBField("documentid", DataType.String, DBOperator.Equal, _DocumentID));
using (IDBSession session = DBSessionManager.Default.GetSession(Common.GetEditWorkSpaceDBConnName()))
{
lists = dao.SelectList(session, "*", filter, "status asc,auditstatus asc,addtime desc");
}
if (TestHashTableKey("Product" + workSpaceID + _DocumentID))
{
hashTableCache.Remove("Product" + workSpaceID + _DocumentID);
}
hashTableCache.Add("Product" + workSpaceID + _DocumentID, lists);
#endregion
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// 获取内容对象
/// </summary>
public class GetObject
{
/// <summary>
/// 获取内容
/// </summary>
/// <param name="_DocumentID">文档ID</param>
/// <returns></returns>
public static ObjectTable<Product> GetCollection(string _DocumentID)
{
string workSpaceID = Common.GetEditWorkSpaceID();
//提供跨工作区调用数据源支持
workSpaceID = SiteHelper.GetObject.GetItem(workSpaceID).Datasource.Value;
if (Convert.ToBoolean(ConfigurationManager.AppSettings[Enum_CacheItem.产品_Product]))
{
if (!TestHashTableKey("Product" + workSpaceID + _DocumentID))
{
Cache(_DocumentID);
}
return (ObjectTable<Product>)hashTableCache["Product" + workSpaceID + _DocumentID];
}
else
{
try
{
IProductDAO dao = DAOManager.Default.GetDAO<IProductDAO>();
QueryFilter filter = new QueryFilter();
if (!isShowDisabled)
{
filter.Items.Add(new DBField("status", DataType.String, DBOperator.Equal, "0"));
}
filter.Items.Add(new DBField("documentid", DataType.String, DBOperator.Equal, _DocumentID));
using (IDBSession session = DBSessionManager.Default.GetSession(Common.GetEditWorkSpaceDBConnName()))
{
return dao.SelectList(session, "*", filter, "status asc,auditstatus asc,addtime desc");
}
}
catch (Exception ex)
{
throw ex;
}
}
}
/// <summary>
/// 根据内容ID获取一个内容
/// </summary>
/// <param name="_ProductID">内容ID</param>
/// <param name="_DocumentID">文档ID</param>
/// <returns></returns>
public static Product GetItem(string _DocumentID, string _ProductID)
{
Product item = null;
ObjectTable<Product> lists = GetCollection(_DocumentID);
for (int i = 0; i < lists.Count; i++)
{
if (lists[i].ID.Value == _ProductID)
{
item = lists[i];
break;
}
}
return item;
}
/// <summary>
/// 获取已经审核的内容
/// </summary>
/// <param name="_DocumentID">文档ID</param>
/// <returns></returns>
public static ObjectTable<Product> GetAuditCollection(string _DocumentID)
{
string workSpaceID = Common.GetEditWorkSpaceID();
//提供跨工作区调用数据源支持
workSpaceID = SiteHelper.GetObject.GetItem(workSpaceID).Datasource.Value;
if (TestHashTableKey("Product" + workSpaceID + _DocumentID + "Audit"))
{
return (ObjectTable<Product>)hashTableCache["Product" + workSpaceID + _DocumentID + "Audit"];
}
else
{
ObjectTable<Product> auditlists = new ObjectTable<Product>();
ObjectTable<Product> lists = GetCollection(_DocumentID);
for (int i = 0; i < lists.Count; i++)
{
if (lists[i].Auditstatus.Value != "0")
{
continue;
}
auditlists.Add(lists[i]);
}
hashTableCache.Add("Product" + workSpaceID + _DocumentID + "Audit", auditlists);
return auditlists;
}
}
/// <summary>
/// 获取已经审核的内容
/// </summary>
/// <param name="_DocumentID">文档ID</param>
/// <param name="_DistillNumber">提取数量</param>
/// <returns></returns>
public static ObjectTable<Product> GetAuditCollection(string _DocumentID, int _DistillNumber)
{
string workSpaceID = Common.GetEditWorkSpaceID();
//提供跨工作区调用数据源支持
workSpaceID = SiteHelper.GetObject.GetItem(workSpaceID).Datasource.Value;
if (TestHashTableKey("Product" + workSpaceID + _DocumentID + "Audit" + _DistillNumber))
{
return (ObjectTable<Product>)hashTableCache["Product" + workSpaceID + _DocumentID + "Audit" + _DistillNumber];
}
else
{
ObjectTable<Product> newauditlists = new ObjectTable<Product>();
ObjectTable<Product> auditlists = GetAuditCollection(_DocumentID);
if (auditlists.Count <= _DistillNumber)
{
newauditlists = auditlists;
}
else
{
for (int i = 0; i < _DistillNumber; i++)
{
newauditlists.Add(auditlists[i]);
}
}
hashTableCache.Add("Product" + workSpaceID + _DocumentID + "Audit" + _DistillNumber, auditlists);
return auditlists;
}
}
/// <summary>
/// 获取未审核的内容
/// </summary>
/// <param name="_DocumentID">文档ID</param>
/// <returns></returns>
public static ObjectTable<Product> GetNotAuditCollection(string _DocumentID)
{
string workSpaceID = Common.GetEditWorkSpaceID();
//提供跨工作区调用数据源支持
workSpaceID = SiteHelper.GetObject.GetItem(workSpaceID).Datasource.Value;
if (TestHashTableKey("Product" + workSpaceID + _DocumentID + "NotAudit"))
{
return (ObjectTable<Product>)hashTableCache["Product" + workSpaceID + _DocumentID + "NotAudit"];
}
else
{
ObjectTable<Product> notauditlists = new ObjectTable<Product>();
ObjectTable<Product> lists = GetCollection(_DocumentID);
for (int i = 0; i < lists.Count; i++)
{
if (lists[i].Auditstatus.Value != "1")
{
continue;
}
notauditlists.Add(lists[i]);
}
hashTableCache.Add("Product" + workSpaceID + _DocumentID + "NotAudit", notauditlists);
return notauditlists;
}
}
/// <summary>
/// 获取审核未通过的内容
/// </summary>
/// <param name="_DocumentID">文档ID</param>
/// <returns></returns>
public static ObjectTable<Product> GetNotPassAuditCollection(string _DocumentID)
{
string workSpaceID = Common.GetEditWorkSpaceID();
//提供跨工作区调用数据源支持
workSpaceID = SiteHelper.GetObject.GetItem(workSpaceID).Datasource.Value;
if (TestHashTableKey("Product" + workSpaceID + _DocumentID + "NotPassAudit"))
{
return (ObjectTable<Product>)hashTableCache["Product" + workSpaceID + _DocumentID + "NotPassAudit"];
}
else
{
ObjectTable<Product> notpassauditlists = new ObjectTable<Product>();
ObjectTable<Product> lists = GetCollection(_DocumentID);
for (int i = 0; i < lists.Count; i++)
{
if (lists[i].Auditstatus.Value != "2")
{
continue;
}
notpassauditlists.Add(lists[i]);
}
hashTableCache.Add("Product" + workSpaceID + _DocumentID + "NotPassAudit", notpassauditlists);
return notpassauditlists;
}
}
}
/// <summary>
/// 缓存同步
/// </summary>
public class CacheSynchronize
{
/// <summary>
/// Product缓存同步-Insert
/// </summary>
/// <param name="_Product">要插入的字典对象</param>
/// <param name="_DocumentID">文档ID</param>
public static void Insert(IProductParam _Product, string _DocumentID)
{
string workSpaceID = Common.GetEditWorkSpaceID();
//提供跨工作区调用数据源支持
workSpaceID = SiteHelper.GetObject.GetItem(workSpaceID).Datasource.Value;
if (!Convert.ToBoolean(ConfigurationManager.AppSettings[Enum_CacheItem.产品_Product]))
{
return;
}
if (!TestHashTableKey("Product" + workSpaceID + _DocumentID))
{
Cache(_DocumentID);
return;
}
Product newitem = new Product();
string[] setFileds = newitem.GetFieldNames();
string[] getFlieds = _Product.GetFieldNames();
if (setFileds != getFlieds)
{
if (!cacheExceptionHandle)
{
throw (new Exception("传入的对象数据结构与Product结构不一致,缓存同步操作不能继续,您可以通过重载缓存来跳过缓存同步操作!"));
}
else
{
Cache(_DocumentID);
return;
}
}
try
{
for (int i = 0; i < setFileds.Length; i++)
{
newitem.SetPropertyValueByFieldName(setFileds[i], _Product.GetPropertyByFieldName(getFlieds[i]).Value);
}
if (TestHashTableKey("Product" + workSpaceID + _DocumentID))
{
hashTableCache.Remove("Product" + workSpaceID + _DocumentID);
}
((ObjectTable<Product>)hashTableCache["Product" + workSpaceID + _DocumentID]).Add(newitem);
}
catch (Exception ex)
{
if (!cacheExceptionHandle)
{
throw ex;
}
else
{
Cache(_DocumentID);
}
}
finally
{
hashTableCache.Remove("Product" + workSpaceID + _DocumentID + "NotAudit");
ProductHelper.GetObject.GetNotAuditCollection(_DocumentID);
}
}
/// <summary>
/// Category缓存同步-Delete
/// </summary>
/// <param name="_Product">内容ID</param>
/// <param name="_DocumentID">文档ID</param>
public static void Delete(string _Product, string _DocumentID)
{
string workSpaceID = Common.GetEditWorkSpaceID();
//提供跨工作区调用数据源支持
workSpaceID = SiteHelper.GetObject.GetItem(workSpaceID).Datasource.Value;
if (!Convert.ToBoolean(ConfigurationManager.AppSettings[Enum_CacheItem.产品_Product]))
{
return;
}
if (!TestHashTableKey("Product" + workSpaceID + _DocumentID))
{
Cache(_DocumentID);
return;
}
try
{
bool isExit = false;
for (int i = 0; i < ((ObjectTable<Product>)hashTableCache["Product" + workSpaceID + _DocumentID]).Count; i++)
{
if (((ObjectTable<Product>)hashTableCache["Product" + workSpaceID + _DocumentID])[i].ID.Value == _Product)
{
((ObjectTable<Product>)hashTableCache["Product" + workSpaceID + _DocumentID]).Remove(((ObjectTable<Product>)hashTableCache["Product" + workSpaceID + _DocumentID])[i]);
isExit = true;
break;
}
}
//如未查询到要删除的记录则认为HashTable已经在其他地方被修改,数据已经不能同步,需要重新载入字典缓存
if (!isExit)
{
Cache(_DocumentID);
}
}
catch (Exception ex)
{
if (!cacheExceptionHandle)
{
throw ex;
}
else
{
Cache(_DocumentID);
}
}
finally
{
hashTableCache.Remove("Product" + workSpaceID + _DocumentID + "Audit");
ProductHelper.GetObject.GetAuditCollection(_DocumentID);
hashTableCache.Remove("Product" + workSpaceID + _DocumentID + "NotAudit");
ProductHelper.GetObject.GetNotAuditCollection(_DocumentID);
hashTableCache.Remove("Product" + workSpaceID + _DocumentID + "NotPassAudit");
ProductHelper.GetObject.GetNotPassAuditCollection(_DocumentID);
}
}
/// <summary>
/// Category缓存同步-Update
/// </summary>
/// <param name="_Product">要更新的IProductParam对象</param>
/// <param name="_DocumentID">文档ID</param>
public static void Update(IProductParam _Product, string _DocumentID)
{
string workSpaceID = Common.GetEditWorkSpaceID();
//提供跨工作区调用数据源支持
workSpaceID = SiteHelper.GetObject.GetItem(workSpaceID).Datasource.Value;
if (!Convert.ToBoolean(ConfigurationManager.AppSettings[Enum_CacheItem.产品_Product]))
{
return;
}
if (!TestHashTableKey("Product" + workSpaceID + _DocumentID))
{
Cache(_DocumentID);
return;
}
Product newitem = new Product();
string[] setFileds = newitem.GetFieldNames();
string[] getFlieds = _Product.GetFieldNames();
if (setFileds != getFlieds)
{
if (!cacheExceptionHandle)
{
throw (new Exception("传入的对象数据结构与Product结构不一致,缓存同步操作不能继续,您可以通过重载缓存来跳过缓存同步操作!"));
}
else
{
Cache(_DocumentID);
return;
}
}
bool isExit = false;
try
{
for (int i = 0; i < ((ObjectTable<Product>)hashTableCache["Product" + workSpaceID + _DocumentID]).Count; i++)
{
if (((ObjectTable<Product>)hashTableCache["Product" + workSpaceID + _DocumentID])[i].ID.Value == _Product.ID.Value)
{
for (int j = 1; j < getFlieds.Length; j++)
{
if (_Product.GetPropertyByFieldName(getFlieds[j]).Value == null)
{
continue;
}
((ObjectTable<Product>)hashTableCache["Product" + workSpaceID + _DocumentID])[i].SetPropertyValueByFieldName(getFlieds[j], _Product.GetPropertyByFieldName(getFlieds[j]).Value);
}
isExit = true;
break;
}
}
//如未查询到要删除的记录则认为HashTable已经在其他地方被修改,数据已经不能同步,需要重新载入字典缓存
if (!isExit)
{
Cache(_DocumentID);
}
}
catch (Exception ex)
{
if (!cacheExceptionHandle)
{
throw ex;
}
else
{
Cache(_DocumentID);
}
}
finally
{
hashTableCache.Remove("Product" + workSpaceID + _DocumentID + "Audit");
ProductHelper.GetObject.GetAuditCollection(_DocumentID);
hashTableCache.Remove("Product" + workSpaceID + _DocumentID + "NotAudit");
ProductHelper.GetObject.GetNotAuditCollection(_DocumentID);
hashTableCache.Remove("Product" + workSpaceID + _DocumentID + "NotPassAudit");
ProductHelper.GetObject.GetNotPassAuditCollection(_DocumentID);
}
}
}
}
}