代码改变世界

使用EnterpriseLibrary5实现数据的缓存(附完整代码下载)

2011-04-28 10:05  Bingo Lee  阅读(2674)  评论(4编辑  收藏  举报

本例子演示了如何使用微软企业类库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 });