.NetCore 内置缓存加入到EFCore操作中,数据更新或者查询时自动更新缓存。github地址

2019-04-27 初步完成逻辑代码编写,尚未经过测试,诸多细节有待完善。

2019-04-28 简单功能测试及部分错误逻辑修改。

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; namespace FXY_NetCore_DbContext
{
public class DefaultContext
{
/// <summary>
/// a queue to save the handle,if will be empted when call savechanges().
/// </summary>
private ConcurrentQueue<CacheEntity> CacheQueue { get; set; } /// <summary>
/// databse context.
/// </summary>
private DbContext Context { get; set; } /// <summary>
/// netocre inner cache.
/// </summary>
private IMemoryCache Cache { get; set; } /// <summary>
/// the time of cache's life cycle
/// </summary>
private int ExpirtTime { get; set; } = 10; /// <summary>
/// entity context.
/// </summary>
/// <param name="context">database context</param>
/// <param name="cache">cache</param>
/// <param name="expirtTime">expirt time,default 60 sencond.</param>
public DefaultContext(DbContext context, IMemoryCache cache, int expirtTime = 10)
{
CacheQueue = new ConcurrentQueue<CacheEntity>();
Context = context;
Cache = cache;
ExpirtTime = expirtTime;
} /// <summary>
/// add entity to database context and add the handle to the queue.
/// <para>it will be excuted when call Savechange().</para>
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="entity"></param>
public void Add<TEntity>(TEntity entity)
where TEntity : class, new()
{
Context.Add(entity);
} /// <summary>
/// add entity list to database context and add the handle to the queue.
/// <para>it will be excuted when call Savechange().</para>
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="entities"></param>
public void AddRange<TEntity>(params TEntity[] entities)
where TEntity : class, new()
{
foreach (var item in entities)
Add(item);
} /// <summary>
/// remove entity to database context and add the handle to the queue.
/// <para>it will be excuted when call Savechange().</para>
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="entity"></param>
public void Remove<TEntity>(TEntity entity)
where TEntity : class, new()
{
bool reesult = Enqueue(entity);
if (reesult)
Context.Remove(entity);
} /// <summary>
/// remove entity list to database context and add the handle to the queue.
/// <para>it will be excuted when call Savechange().</para>
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="entities"></param>
public void RemoveRange<TEntity>(params TEntity[] entities)
where TEntity : class, new()
{
foreach (var item in entities)
Remove(item);
} /// <summary>
/// update entity to database context and add the handle to the queue.
/// <para>it will be excuted when call Savechange().</para>
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="entity"></param>
public void Update<TEntity>(TEntity entity)
where TEntity : class, new()
{
bool reesult = Enqueue(entity);
if (reesult)
Context.Update(entity);
} /// <summary>
/// update entity list to database context and add the handle to the queue.
/// <para>it will be excuted when call Savechange().</para>
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="entities"></param>
public void UpdateRange<TEntity>(params TEntity[] entities)
where TEntity : class, new()
{
foreach (var item in entities)
Update(item);
} /// <summary>
/// attach entity to database context add the handle to the queue.
/// <para>it will be excuted when call Savechange().</para>
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="entities"></param>
public void Attach<TEntity>(TEntity entity)
where TEntity : class, new()
{
bool reesult = Enqueue(entity);
if (reesult)
Context.Attach(entity);
} /// <summary>
/// attach entity list to database context add the handle to the queue.
/// <para>it will be excuted when call Savechange().</para>
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="entities"></param>
public void AttachRange<TEntity>(params TEntity[] entities)
where TEntity : class, new()
{
foreach (var item in entities)
Attach(item);
} /// <summary>
/// update cache and database.
/// <para>update cache at first,if update cache is failed,return false,else commit the changes to database.</para>
/// </summary>
/// <returns></returns>
public bool SaveChanges()
{
bool result = Dequeue();
if (result)
result = Context.SaveChanges() > 0;
return result;
} /// <summary>
/// single query.
/// <para>find it in the cache first,return if find it,otherwise search it in database by efcore.</para>
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="key"></param>
/// <returns></returns>
public TEntity Get<TEntity>(string key)
where TEntity : class, new()
{
var result = GetCache<TEntity>(key);
if (result == null)
{
result = Context.Find<TEntity>(key);
var cacheEntity = GetCacheEntity(result);
AddCache(cacheEntity);
}
else
{
var cacheEntity = GetCacheEntity(result);
UpdateCache(cacheEntity);
}
return result;
} /// <summary>
/// collection query.
/// <para>do not allow fuzzy query</para>
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="keys"></param>
/// <returns></returns>
public List<TEntity> Get<TEntity>(string[] keys)
where TEntity : class, new()
{
var result = new List<TEntity>();
foreach (var item in keys)
result.Add(Get<TEntity>(item));
return result;
} #region private #region cache queue /// <summary>
/// add the handle to the context queue.
/// </summary>
/// <param name="model"></param>
/// <param name="handleEnum"></param>
private bool Enqueue(object model)
{
CacheEntity entity = GetCacheEntity(model);
if (CacheQueue.TryPeek(out CacheEntity cacheEntity1))
return false;
else
{
CacheQueue.Enqueue(entity);
return CacheQueue.TryPeek(out CacheEntity cacheEntity2);
}
} /// <summary>
/// update the changes to cache,and remove it from the cache queue.
/// <para>include add,delete and update.</para>
/// </summary>
/// <returns></returns>
private bool Dequeue()
{
bool check = false;
bool dequeue = CacheQueue.TryDequeue(out CacheEntity cacheEntity);
if (dequeue)
check = RemoveCache(cacheEntity);
else
check = false;
return check;
} #endregion #region cache core /// <summary>
/// add cache
/// </summary>
/// <param name="cacheEntity"></param>
/// <returns></returns>
private bool AddCache(CacheEntity cacheEntity)
{
bool check;
Cache.Set(cacheEntity.key, cacheEntity.Value, new TimeSpan(0, 0, ExpirtTime));
check = Cache.Get(cacheEntity.key) != null;
return check;
} /// <summary>
/// remove cache.
/// </summary>
/// <param name="cacheEntity"></param>
/// <returns></returns>
private bool RemoveCache(CacheEntity cacheEntity)
{
bool check;
Cache.Remove(cacheEntity.key);
check = Cache.Get(cacheEntity.key) == null;
return check;
} /// <summary>
/// update cache.
/// </summary>
/// <param name="cacheEntity"></param>
/// <returns></returns>
private bool UpdateCache(CacheEntity cacheEntity)
{
bool check = RemoveCache(cacheEntity);
if (check)
check = AddCache(cacheEntity);
return check;
} /// <summary>
/// get cache by key.
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <returns></returns>
private TEntity GetCache<TEntity>(string key)
where TEntity : class, new()
{
Cache.TryGetValue(key, out object value);
return value as TEntity;
} #endregion #region other /// <summary>
/// get private cache entity.
/// </summary>
/// <param name="model"></param>
/// <param name="handleEnum"></param>
/// <returns></returns>
private CacheEntity GetCacheEntity(object model)
{
var key = GetModelKey(model);
var entity = new CacheEntity()
{
Value = model,
key = key
};
return entity;
} /// <summary>
/// get the key of a entity.
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
private string GetModelKey(object model)
{
string key = "";
var type = model.GetType().GetProperties();
foreach (var item in type)
{
if (item.GetCustomAttributes(typeof(KeyAttribute), true).Length > 0)
{
key = item.GetValue(model).ToString();
break;
}
}
return key;
} #endregion
#endregion
} /// <summary>
/// a entity to handle cache
/// </summary>
public sealed class CacheEntity
{
/// <summary>
/// cache key
/// </summary>
[Key]
public string key { get; set; } /// <summary>
/// cache value
/// </summary>
public object Value { get; set; }
}
}

基于EFCore的数据Cache实现的更多相关文章

  1. 基于Web的数据推送技术(转)

    基于Web的数据推送技术 对于实时性数据显示要求比较高的系统,比如竞价,股票行情,实时聊天等,我们的解决方案有以下几种.1. HTTP请求发送模式,一般可以基于ajax的请求,比如每3秒一次访问下服务 ...

  2. 【转】在Spring中基于JDBC进行数据访问时怎么控制超时

    http://www.myexception.cn/database/1651797.html 在Spring中基于JDBC进行数据访问时如何控制超时 超时分类 超时根据作用域可做如下层级划分: Tr ...

  3. 数据权限设计——基于EntityFramework的数据权限设计方案:一种设计思路

    前言:“我们有一个订单列表,希望能够根据当前登陆的不同用户看到不同类型的订单数据”.“我们希望不同的用户能看到不同时间段的扫描报表数据”.“我们系统需要不同用户查看不同的生产报表列”.诸如此类,最近经 ...

  4. 基于 PHP 的数据爬取(QueryList)

    基于PHP的数据爬取 官方网站站点 简单. 灵活.强大的PHP采集工具,让采集更简单一点. 简介: QueryList使用jQuery选择器来做采集,让你告别复杂的正则表达式:QueryList具有j ...

  5. Creating adaptive web recommendation system based on user behavior(设计基于用户行为数据的适应性网络推荐系统)

    文章介绍了一个基于用户行为数据的推荐系统的实现步骤和方法.系统的核心是专家系统,它会根据一定的策略计算所有物品的相关度,并且将相关度最高的物品序列推送给用户.计算相关度的策略分为两部分,第一部分是针对 ...

  6. 基于CentOS搭建基于 ZIPKIN 的数据追踪系统

    系统要求:CentOS 7.2 64 位操作系统 配置 Java 环境 安装 JDK Zipkin 使用 Java8 -openjdk* -y 安装完成后,查看是否安装成功: java -versio ...

  7. 基于PHP采集数据入库程序(二)

    在上篇基于PHP采集数据入库程序(一) 中提到采集新闻信息页的列表数据,接下来讲讲关于采集新闻具体内容 这是上篇博客的最终数据表截图: 接下来要做的操作就是从数据库中读取所需要采集的URL,进行页面抓 ...

  8. 基于Dedup的数据打包技术

    基于Dedup的数据打包技术 0.引言    Tar, winrar, winzip是最为常见的数据打包工具软件,它们把文件集体封装成一个单独的数据包,从而方便数据的分布.传输.归档以及持久保存等目的 ...

  9. 基于vue-easytable实现数据的增删改查

    基于vue-easytable实现数据的增删改查 原理:利用vue的数据绑定和vue-easetable的ui完成增删改查 后端接口: 1.条件查询表中数据 http://localhost:4795 ...

随机推荐

  1. 添加git 忽略文件

    在使用Git的过程中,我们喜欢有的文件比如日志,临时文件,编译的中间文件等不要提交到代码仓库,这时就要设置相应的忽略规则,来忽略这些文件的提交. Git 忽略文件提交的方法 有三种方法可以实现忽略Gi ...

  2. hystrix -hystrixCommand配置介绍

    public @interface HystrixCommand { // HystrixCommand 命令所属的组的名称:默认注解方法类的名称 String groupKey() default ...

  3. MongoDB中MapReduce不同的写法,不同的结果

    MapReduce有两种写法,也可以说mongodb所有的命令行都有两种写法. 但突然间发现MapReduce不同的写法会有不同的结果,接下来我们一起来看: 第一种:直接使用扩展属性. 1)emit函 ...

  4. SpringXML方式配置bean的懒加载lazy-init

    lazy-init(懒加载),表示该bean在容器初始化的时候不进行初始化. 例如: <bean name="role1" class="com.fz.entity ...

  5. jinfo用法说明

    以下几种用法 -flags pid :打印当前VM的参数 -flag <name> pid:打印指定JVM的参数值 -flag [+|-]<name> pid:设置指定JVM参 ...

  6. Python模块化

    在Python中,一个.py文件就称之为一个模块(Module). 模块化的好处: 1.大大提高了代码的可维护性. 2.编写代码不必从零开始.当一个模块编写完毕,就可以被其他地方引用.我们在编写程序的 ...

  7. sed和awk简介

    什么是sed和awk         sed和awk是Linux环境下数据的处理工具,可以完成对数据的增删改查的功能.         sed处理时是以行尾单位的,awk处理数据时以字段为单位. se ...

  8. Jquery如何获取ASP.NET服务器控件的值

    关键字: Jquery 服务器控件 获取值 由于ASP.NET网页运行后,服务器控件会随机生成客户端id,jquery获取时候不太好操作,总结有以下3种方法:   服务器控件代码:<asp:Te ...

  9. Ubuntu循环登录libGL error: fbConfigs swrast等

    Ubuntu16.04更新NVIDIA驱动后,无法进入桌面,使用vim .xsession-errors 查看错误信息,如下: libGL error: No matching fbConfigs o ...

  10. YXY-压测

    1.首先介绍一下组件Synchronizing Timer Number of Simulated users to Group by:集合点集合够N个用户开始并发 Timeout in millis ...