不说多得直接上代码:
public class DataCacheCommon<T> where T : class
{
private List<T> DataList = new List<T>();
private static object ulock = new object();
private DateTime nextDataUpdate = DateTime.Now;
/// <summary>
/// 每次从数据库更新的间隔为60分钟
/// </summary>
private int updateInterval = 60;
public delegate List<T> UpdateDataFunction();
/// <summary>
/// 实例化对象时,必须提供更新数据的方法
/// </summary>
/// <param name="?"></param>
private DataCacheCommon(UpdateDataFunction Function)
{
Type type = typeof(T);
new DalBaseData<SysRunLogs>().AddEntity(new SysRunLogs() {
AddDateTime=DateTime.Now,
LoginInfo = "启动实例化 " + type.Name
});
OnTimeUpdateDataList(Function);
}
private DataCacheCommon()
{ }
private static DataCacheCommon<T> instance = null;
private static readonly object padlock = new object();
/// <summary>
/// 单例模式创建
/// </summary>
/// <param name="updateTime"></param>
/// <returns></returns>
public static DataCacheCommon<T> Instance(UpdateDataFunction updateTime)
{
if (instance == null)
{
lock (padlock)
{
if (instance == null)
{
instance = new DataCacheCommon<T>(updateTime);
}
}
}
return instance;
}
/// <summary>
/// 操作类型
/// </summary>
private enum OperType
{
Select = 1,
Update = 2,
Delete = 3,
Add = 4
}
/// <summary>
/// 更新实体
/// </summary>
/// <param name="model">新的实体对象</param>
/// <param name="query">原有的实体对象</param>
public void Update(T model, Func<T, bool> query)
{
DataOper(OperType.Update, model, query);
}
/// <summary>
/// 增加实体
/// </summary>
/// <param name="model"></param>
public void Add(T model)
{
DataOper(OperType.Add, model, null);
}
/// <summary>
/// 根据条件删除数据方法
/// </summary>
/// <param name="query"></param>
public void Delete(Func<T, bool> query)
{
DataOper(OperType.Delete, null, query);
}
/// <summary>
/// 根据尸体数据删除方法
/// </summary>
/// <param name="Entity"></param>
public void Delete(T Entity)
{
DataOper(OperType.Delete, Entity, null);
}
/// <summary>
/// 根据尸体数据删除方法
/// </summary>
/// <param name="Entity"></param>
public void Delete(Expression<Func<T, bool>> query)
{
DataOper(OperType.Delete, null, query.Compile());
}
public List<T> GetDataList(Func<T, bool> query)
{
return DataOper(OperType.Select, null, query);
}
public List<T> GetDataList(Expression<Func<T, bool>> query)
{
return DataOper(OperType.Select, null, query.Compile());
}
public List<T> GetDataList()
{
return DataOper(OperType.Select, null, null);
}
public List<T> GetDataList(Expression<Func<T, bool>> query, PagingInfo PageInfo, Func<T, object> orderByDesc)
{
List<T> DataWhere=DataOper(OperType.Select, null, query.Compile());
PageInfo.TotalRecord = DataWhere.Count();
PageInfo.TotalPage = PageInfo.TotalRecord / PageInfo.PageSize + 1;
return (from t in DataWhere
select t).OrderByDescending(orderByDesc).Skip(PageInfo.PageSize * (PageInfo.PageIndex - 1)).Take(PageInfo.PageSize).ToList();
}
/// <summary>
/// 下一次更新时间
/// </summary>
public DateTime NextDataUpdate
{
set
{
nextDataUpdate = value;
}
}
/// <summary>
/// 每次从数据更新时间,默认为60分钟更新一次
/// </summary>
public int UpdateInterval
{
get
{
return updateInterval;
}
set
{
updateInterval = value;
}
}
/// <summary>
/// 调用更新数据的线程方法
/// </summary>
/// <param name="Function"></param>
private void OnTimeUpdateDataList(UpdateDataFunction Function)
{
ParameterizedThreadStart ParStart = new ParameterizedThreadStart(UpdateData);
Thread myThread = new Thread(ParStart);
object o = Function;
myThread.Start(o);
}
/// <summary>
/// 数据定时更新的方法
/// </summary>
private void UpdateData(object Function)
{
while (true)
{
if (nextDataUpdate <= DateTime.Now)
{
DataList = (List<T>)((UpdateDataFunction)Function)();
Type type = typeof(T);
new DalBaseData<SysRunLogs>().AddEntity(new SysRunLogs()
{
AddDateTime = DateTime.Now,
LoginInfo = "更新缓存 " + type.Name + " 数据 " + DataList.Count()+" 条!"
});
nextDataUpdate = nextDataUpdate.AddMinutes(UpdateInterval);// UpdateInterval*60*1000;
}
Thread.Sleep(1000);
}
}
/// <summary>
/// 公共列表操作类
/// </summary>
/// <param name="OperType">操作类型(select update delete add/insert)</param>
/// <param name="model">实体对象 修改和增加 删除的时候必须传入</param>
/// <param name="query">当为select时候的查询条件</param>
/// <returns>当为select则返回 list列表 否则不进行返回</returns>
private List<T> DataOper(OperType operType, T model, Func<T, bool> query)
{
if (DataList == null)
{
DataList = new List<T>();
}
lock (ulock)
{
switch (operType)
{
case OperType.Select:
if (query == null)
{
return DataList;
}
return DataList.Where(query).ToList();
case OperType.Update:
T tmodel = DataList.Where(query).FirstOrDefault();
if (tmodel != null)
{
tmodel = Clone(model);
}
return null;
case OperType.Delete:
if (query != null)
{
List<T> DeleteList = DataList.Where(query).ToList();
if (DeleteList != null)
{
foreach (var item in DeleteList)
{
DataList.Remove(item);
}
}
}
else if (model != null)
{
DataList.Remove(model);
}
return null;
case OperType.Add:
DataList.Add(model);
return null;
}
return null;
}
}
/// <summary>
/// 数据复制
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="RealObject"></param>
/// <returns></returns>
public static T Clone<T>(T RealObject)
{
using (Stream objectStream = new MemoryStream())
{
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(objectStream, RealObject);
objectStream.Seek(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(objectStream);
}
}
/// <summary>
/// 数据复制
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entity"></param>
/// <returns></returns>
public T Copy<T>(T entity) where T : class
{
Type type = typeof(T);
T newEntity = System.Activator.CreateInstance<T>(); ;
object propertyValue = null;
PropertyInfo[] properties1 = newEntity.GetType().GetProperties();
foreach (PropertyInfo property in properties1)
{
propertyValue = null;
if (null != property.GetSetMethod())
{
PropertyInfo entityProperty =
entity.GetType().GetProperty(property.Name);
if (entityProperty.PropertyType.BaseType ==
Type.GetType("System.ValueType") ||
entityProperty.PropertyType ==
Type.GetType("System.String"))
propertyValue = entity.GetType().GetProperty(property.Name).GetValue(entity, null);
if (propertyValue == null)
{
propertyValue = entity.GetType().GetProperty(property.Name).GetValue(entity, null);
}
if (null != propertyValue)
{
try
{
string Name = property.Name;// "Reference";
if (Name.IndexOf("Reference") < 0)
{
property.SetValue(entity, propertyValue, null);
}
}
catch (Exception ex) { }
}
}
}
return newEntity;
}
}
这个类是我想在Dal层想做一个,公共缓存的一个积累,但是上一篇文章页提到,因为锁会造成操作的相互影响,从而造成延迟的问题。但是,如果去掉锁,会造成数据的错乱。所以希望大家在这里多多提修改意见。这个也是我基于EF的一个封装