本例子演示了如何使用微软企业类库5.0实现数据的缓存。
1,打开visual studio 2010,新建一个winform项目,并命名为CachingByEnterpriseLibrary5。
2,添加如下引用
- Microsoft.Practices.EnterpriseLibrary.Caching (C:\Program Files\Microsoft Enterprise Library 5.0\Bin\Microsoft.Practices.EnterpriseLibrary.Caching.dll)
- Microsoft.Practices.EnterpriseLibrary.Common (C:\Program Files\Microsoft Enterprise Library 5.0\Bin\Microsoft.Practices.EnterpriseLibrary.Common.dll)
- Microsoft.Practices.ServiceLocation (C:\Program Files\Microsoft Enterprise Library 5.0\Bin\Microsoft.Practices.ServiceLocation.dll)
说明:EnterpriseLibrary5.0 下载地址
3,新增数据访问类 DataAccessLayer.cs,数据库使用的微软示例数据库Northwind。
using System;
using System.Collections.ObjectModel;
using System.Data.SqlClient;
namespace CachingByEnterpriseLibrary5
{
public class Employee
{
public int Id { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public string Title { get; set; }
public DateTime BirthDate { get; set; }
public string City { get; set; }
}
class DataAccess
{
SqlConnection Conn;
SqlCommand Command;
SqlDataReader Reader;
public DataAccess()
{
Conn = new SqlConnection("Data Source=.;Initial Catalog=Northwind;Integrated Security=SSPI");
}
public ObservableCollection<Employee> GetEmployees()
{
ObservableCollection<Employee> lstEmployees = new ObservableCollection<Employee>();
Conn.Open();
Command = new SqlCommand();
Command.Connection = Conn;
Command.CommandText = "select * from Employees";
Reader = Command.ExecuteReader();
while (Reader.Read())
{
lstEmployees.Add(new Employee()
{
Id = Convert.ToInt32(Reader["EmployeeID"]),
LastName = Reader["LastName"].ToString(),
FirstName = Reader["FirstName"].ToString(),
Title = Reader["Title"].ToString(),
BirthDate = Convert.ToDateTime(Reader["BirthDate"]),
City = Reader["City"].ToString()
});
}
Reader.Close();
Conn.Close();
return lstEmployees;
}
}
}
4,增加数据缓存类CachingInfrastructure.cs
using System;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.Practices.EnterpriseLibrary.Caching;
using Microsoft.Practices.EnterpriseLibrary.Caching.Expirations;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
namespace CachingByEnterpriseLibrary5
{
public class CachingInfrastructure
{
static ObservableCollection<Employee> lstEmployee = null;
static ICacheManager cacheEmployeeData;
public CachingInfrastructure()
{
}
public static ObservableCollection<Employee> GetEmployeeData(out string cacheStatus)
{
//尝试从缓存中读取数据
cacheEmployeeData = EnterpriseLibraryContainer.Current.GetInstance<ICacheManager>();
lstEmployee = (ObservableCollection<Employee>)cacheEmployeeData["EmployeeDataCache"];
cacheStatus = "从缓存中读取全部员工数据";
//如果缓存中没有任何数据,那么直接从数据访问层读取
if (lstEmployee == null)
{
DataAccess da = new DataAccess();
lstEmployee = da.GetEmployees();
//定义缓存的有效期限(为了演示缓存效果,设置为10s)
AbsoluteTime CacheExpiretionTime = new AbsoluteTime(new TimeSpan(0, 0, 10));
//把数据放入缓存
cacheEmployeeData.Add("EmployeeDataCache", lstEmployee, CacheItemPriority.High, null, new ICacheItemExpiration[] { CacheExpiretionTime });
cacheStatus = "员工的信息刚被放入缓存中";
}
return lstEmployee;
}
public static Employee GetEmployeeById(int id, out string cacheStatus)
{
Employee emp = null;
emp = (from e in lstEmployee
where e.Id == id
select e).FirstOrDefault();
cacheStatus = "从缓存中读取指定id的员工信息";
return emp;
}
public static void ClearCache(out string cacheStatus)
{
ICacheManager cacheEmployeeData = EnterpriseLibraryContainer.Current.GetInstance<ICacheManager>();
cacheEmployeeData.Flush();
cacheStatus = "缓存已被清空";
}
}
}
5,增加App.Config文件,然后右键该文件。
在弹出的对话框中选中 ‘Blocks’-> ‘Add Caching Settings’
6,Form1界面效果如下图所示
代码如下:
using System;
using System.Collections.ObjectModel;
using System.Windows.Forms;
namespace CachingByEnterpriseLibrary5
{
public partial class Form1 : Form
{
ObservableCollection<Employee> lstEmployee = new ObservableCollection<Employee>();
string cacheStauts = string.Empty;//缓存状态
public Form1()
{
InitializeComponent();
}
//加载员工信息
private void btnLoadData_Click(object sender, EventArgs e)
{
lstEmployee = CachingInfrastructure.GetEmployeeData(out cacheStauts);
lblCacheStatus.Text = cacheStauts;
foreach (var emp in lstEmployee)
{
cmbEmployee.Items.Add(new Item(emp.LastName, emp.Id));
}
cmbEmployee.DroppedDown = true;
cmbEmployee.SelectedValueChanged += new System.EventHandler(cmbEmployee_SelectedIndexChanged);
}
//读取指定Id的员工信息
private void cmbEmployee_SelectedIndexChanged(object sender, EventArgs e)
{
int Id = Convert.ToInt32(((Item)cmbEmployee.SelectedItem).Value);
Employee Emp = CachingInfrastructure.GetEmployeeById(Id, out cacheStauts);
lblCacheStatus.Text = cacheStauts;
txtId.Text = Emp.Id.ToString();
txtFirstName.Text = Emp.FirstName;
txtLastName.Text = Emp.LastName;
txtTitle.Text = Emp.Title;
txtCity.Text = Emp.City;
txtBirthDate.Text = Emp.BirthDate.ToShortDateString();
}
//手工清空缓存
private void btnClearCache_Click(object sender, EventArgs e)
{
CachingInfrastructure.ClearCache(out cacheStauts);
lblCacheStatus.Text = cacheStauts;
cmbEmployee.Items.Clear();
cmbEmployee.Text = "";
txtId.Text = "";
txtFirstName.Text = "";
txtLastName.Text = "";
txtTitle.Text = "";
txtCity.Text = "";
txtBirthDate.Text = "";
lstEmployee.Clear();
}
}
}
为了手工控制ComboBox,添加自定义类文件Item.cs
namespace CachingByEnterpriseLibrary5
{
//为了方便控制combobox,采用自定义类Item给combobox添加项目
public class Item
{
public string Name;
public int Value;
public Item(string name, int value)
{
Name = name; Value = value;
}
public override string ToString()
{
// Generates the text shown in the combo box
return Name;
}
}
}
7,如何验证是从缓存中读取的数据还是从数据库读取的数据?可以使用SQL Server的事件探查器来跟踪应用程序是否执行了相应的
SQL脚本来验证。打开事件探查器(sql server profiler)后,连续双击“加载数据“按钮即可!
看上图中两条被选中的记录间隔的时间正好10s,这也验证了下列代码
//定义缓存的有效期限(为了演示缓存效果,设置为10s)
AbsoluteTime CacheExpiretionTime = new AbsoluteTime(new TimeSpan(0, 0, 10));
//把数据放入缓存cacheEmployeeData.Add("EmployeeDataCache", lstEmployee, CacheItemPriority.High, null, new ICacheItemExpiration[] { CacheExpiretionTime });