静态数据助手 (ASP.NET 2.0)






4.33/5 (5投票s)
一个用于管理下拉列表静态数据并支持缓存的辅助类。
引言
这是一个简单的辅助类,旨在管理 ASP.NET 应用程序中的静态数据。该辅助类将从 SQL Server 数据库检索多个静态数据表,将数据存储在 DataSet
中,并在应用程序启动时或首次请求时进行缓存。只需一行代码即可从缓存中获取数据并将其绑定到 ListControl
(DropDownList
/ ListBox
/ RadioButtonList
/ CheckBoxList
)。
背景
如果您曾经开发过包含大量 DropDownList
控件的 Web 应用程序,那么您可能会发现自己会重复编写大量代码。需要编写代码从数据库中获取查找数据,缓存数据,并将其绑定到 DropDownList
控件,可能是在多个页面上。
设置数据库
演示应用程序使用 SQL Server 2005 Express Edition 开发,但相同的概念也适用于 SQL Server 2000。演示中有一个简单的数据库,包含三个表,用于存储类别、状态和类型的查找值。有一个存储过程:proc_StaticDataSelect
,用于通过多个结果集检索这三个表的数据。
CREATE PROCEDURE dbo.proc_StaticDataSelect
AS
SET NOCOUNT ON;
SELECT StatusId, Status FROM [Statuses]
SELECT TypeId, Type FROM [Types]
SELECT CategoryId, Category, Description FROM [Categories]
使用代码
在示例应用程序的 App_Code 文件夹中有一个类,名为 StaticData.cs。在该类的顶部附近,有一个名为 Tables
的枚举,其中包含每个结果集的值,并且顺序与存储过程返回的顺序相同。
public enum Tables
{
Statuses = 0,
Types,
Categories
}
公共方法 Bind
从缓存中检索静态数据并将其绑定到 ListControl
(DropDownList
/ ListBox
/ RadioButtonList
/ CheckBoxList
)。它接受 ListControl
和表索引作为参数,还有一个重载版本允许向 ListControl
添加标题行。
将静态数据绑定到名为 TypeFilter
的 DropDownList
<asp:DropDownList ID="TypeFilter" runat="server"></asp:DropDownList>
StaticData.Bind(this.TypeFilter, StaticData.Tables.Types, "All Types");
Tables
枚举用于指示 DataSet
中表的索引。这可以避免使用数字来表示离散值。
公共方法 CacheStaticData
从数据库获取静态数据并将其缓存到 DataSet
中。此方法可以在 Global.asax 的 Application_Start
事件中调用。如果不在应用程序启动时调用;它将在第一次调用 Bind
方法时被调用。
void Application_Start(object sender, EventArgs e)
{
StaticData.CacheStaticData();
}
要为另一个 ListControl
添加数据,只需将一个 SELECT
语句添加到 proc_StaticDataSelect
存储过程中,并在 Tables
枚举中添加相同索引的表名。然后,您就可以将数据绑定到 ListControl
,数据将与其余静态数据一起检索和缓存。
工作原理
在演示中,所有代码都在 StaticData
类中,尽管数据访问代码可以放在单独的类或项目中。GetDataSet
方法建立数据库连接,并通过 SqlDataReader
获取数据。它使用 DataSet
的 Load
方法将多个结果集加载到一个 DataSet
中。*(根据您的配置,您可能需要在 web.config 中修改连接字符串。)*
private static DataSet GetDataSet()
{
SqlDataReader dr = null;
DataSet ds = new DataSet();
try
{
SqlConnection conn = new SqlConnection(
ConfigurationManager.ConnectionStrings[
"StaticDataHelperConnectionString"].ToString());
SqlCommand cmd = new SqlCommand("proc_StaticDataSelect", conn);
conn.Open();
dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
ds.Load(dr, LoadOption.OverwriteChanges,
GetDataTablesValuesArray());
return ds;
}
finally
{
if (dr != null && !dr.IsClosed)
{
dr.Close();
}
}
}
Load
方法的第三个参数需要一个表名字符串数组。GetDataTablesValuesArray
方法从 Tables
枚举生成表名字符串数组。
private static string[] GetDataTablesValuesArray()
{
string[] s = new string[0];
foreach (Tables value in Enum.GetValues(typeof(Tables)))
{
Array.Resize(ref s, s.Length + 1);
s.SetValue(value.ToString(), s.Length - 1);
}
return s;
}
私有属性 StaticDataSet
和公共方法 CacheStaticData
管理 DataSet
的缓存。
private static DataSet StaticDataSet
{
get
{
// Get DataSet from Cache
Cache oCache = System.Web.HttpContext.Current.Cache;
DataSet ds = (DataSet)oCache[StaticDataSetCache];
// If DataSet is not in Cache then generate it and cache it
if (ds == null)
{
ds = CacheStaticData();
}
return ds;
}
}
public static DataSet CacheStaticData()
{
Cache oCache = System.Web.HttpContext.Current.Cache;
// Get Static DataSet
DataSet ds = GetDataSet();
// Insert into cache
oCache.Insert(StaticDataSetCache, ds);
return ds;
}
公共方法 Bind
用于从缓存中检索静态数据并将其绑定到 ListControl
。
public static void Bind(ListControl listControl, Tables tableIndex)
{
Bind(listControl, tableIndex, "");
}
public static void Bind(ListControl listControl,
Tables tableIndex, string header)
{
// Get the DataTable from the cached DataSet
DataTable dt = GetData(tableIndex);
// Set the DataValueField and DataTextField of the LsitControl
listControl.DataValueField = dt.Columns[0].ToString();
listControl.DataTextField = dt.Columns[1].ToString();
// Bind the data to the LsitControl
listControl.DataSource = dt;
listControl.DataBind();
// Add the header row if required
if (header.Length > 0)
{
listControl.Items.Insert(0, new ListItem("- " +
header + " -", "0"));
}
}
此方法从缓存的 DataSet
中以指定的表索引检索 DataTable
。它根据 DataTable
的列名设置 ListControl
的 DataValueField
和 DataTextField
属性,然后将 DataTable
绑定到 ListControl
。
如果传递了 header
字符串参数,它将被插入为顶部的项。
使用限制
此类助手旨在管理静态数据,因此数据会在应用程序的整个生命周期内进行缓存。如果您有允许管理员用户更新查找表的功能,您可以在更新发生时调用 StaticData.CacheStaticData();
方法来刷新缓存的数据。
对于会频繁更改的数据,您可以使用 Cache.Insert
重载设置过期时间。
oCache.Insert(StaticDataSetCache, ds, null, DateTime.Now.AddMinutes(30),
Cache.NoSlidingExpiration);
您也可以设置 SQL Server 2005 的缓存依赖项,但这超出了本文的范围。
关注点
DataSet.Load
方法可以通过 SqlDataReader
将多个结果集从单个存储过程加载到 DataSet
中。缓存此 DataSet
是在 ASP.NET 应用程序中存储多个静态数据表的便捷方法。
历史
- v1.0 - 2006 年 10 月 21 日
- v1.1 - 2006 年 10 月 25 日
在演示中添加了
RadioButtonList
和CheckBoxList
控件。 - v1.2 - 2006 年 11 月 2 日
部分措辞和格式调整。