ORM框架 EF - code first 的封装 优化一
上一节我们讲到对EF(EntityFramework)的初步封装,任何事情都不可能一蹴而就,通过大量的实际项目的实战,也发现了其中的各种问题。在这一章中,我们对上一章的EF_Helper_DG进行优化,主要优化点如下:
1.由DB实体单例模式改为从缓存中获取;
2.加入服务器缓存,协助查询,提升查询性能;
3.优化CUD操作方法的执行方式;
下面直接展示新的EF_Helper_DG 代码:
using LinqKit; //AsExpandable() in linqkit.dll using System; using System.Linq; using System.Linq.Expressions; using System.Data.Entity; using System.Transactions; using QX_Frame.Helper_DG.Configs; namespace QX_Frame.Helper_DG { /* time: 2016-10-30 15:26:05 author: qixiao */ /// <summary> /// EntityFramework CodeFirst Helper /// </summary> /// <typeparam name="Db">DbContext</typeparam> public abstract class EF_Helper_DG<Db> where Db : DbContext { /*the singleton Db */ //private volatile static Db db = null; //volatile find Db in memory not in cache #region The Singleton to new DBEntity_DG //private static readonly object lockHelper = new object(); //static EF_Helper_DG() //{ // if (db == null) // { // lock (lockHelper) // { // if (db == null) // db = System.Activator.CreateInstance<Db>(); // } // } // //close the Validate of EF OnSaveEnabled // db.Configuration.ValidateOnSaveEnabled = false; //} #endregion #region get current dbContext public static DbContext GetCurrentDbContext() { //method 1 : CallContext 该方法有有时候第一次访问不到的bug //CallContext:是线程内部唯一的独用的数据槽(一块内存空间) //Db dbContext = CallContext.GetData("DbContext") as Db; //if (dbContext == null) //线程在内存中没有此上下文 //{ // //create a dbContext to memory if dbContext has not exist // dbContext = System.Activator.CreateInstance<Db>(); // CallContext.SetData("DbContext", dbContext); //} //method 2 : Db dbContext = Cache_Helper_DG.Cache_Get("dbContext") as Db; if (dbContext == null) { //create a dbContext to memory if dbContext has not exist dbContext = System.Activator.CreateInstance<Db>(); Cache_Helper_DG.Cache_Add("dbContext",dbContext); } return dbContext; } #endregion #region Cache Strategy /// <summary> /// edit data cache must update /// </summary> public static void CacheChanges<T>() { if (QX_Frame_Helper_DG_Config.Cache_IsCache) { Cache_Helper_DG.Cache_Delete(nameof(T)); } } /// <summary> /// query cache /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> public static IQueryable<T> GetIQuerybleByCache<T>() where T : class { if (QX_Frame_Helper_DG_Config.Cache_IsCache) { IQueryable<T> iqueryable = Cache_Helper_DG.Cache_Get(nameof(T)) as IQueryable<T>; if (iqueryable == null) { DbContext db = GetCurrentDbContext(); iqueryable = db.Set<T>().AsExpandable(); Cache_Helper_DG.Cache_Add(nameof(T), iqueryable, null, DateTime.Now.AddMinutes(QX_Frame_Helper_DG_Config.Cache_CacheExpirationTime_Minutes), TimeSpan.Zero); } return iqueryable; } else { DbContext db = GetCurrentDbContext(); return db.Set<T>().AsExpandable(); } } #endregion #region Add public static Boolean Add<T>(T entity) where T : class { DbContext db = GetCurrentDbContext(); CacheChanges<T>(); db.Entry<T>(entity).State = EntityState.Added; ; } public static Boolean Add<T>(T entity, out T outEntity) where T : class { DbContext db = GetCurrentDbContext(); CacheChanges<T>(); db.Entry<T>(entity).State = EntityState.Added; outEntity = entity; ; } public static Boolean Add<T>(IQueryable<T> entities) where T : class { DbContext db = GetCurrentDbContext(); CacheChanges<T>(); db.Set<T>().AddRange(entities); ; } #endregion #region Update public static Boolean Update<T>(T entity) where T : class { DbContext db = GetCurrentDbContext(); CacheChanges<T>(); if (db.Entry<T>(entity).State == EntityState.Detached) { db.Set<T>().Attach(entity); db.Entry<T>(entity).State = EntityState.Modified; } else { db.SaveChanges(); return true; } ; } public static Boolean Update<T>(T entity, out T outEntity) where T : class { DbContext db = GetCurrentDbContext(); CacheChanges<T>(); outEntity = entity; if (db.Entry<T>(entity).State == EntityState.Detached) { db.Set<T>().Attach(entity); db.Entry<T>(entity).State = EntityState.Modified; } else { db.SaveChanges(); return true; } ; } #endregion #region Delete public static Boolean Delete<T>(T entity) where T : class { DbContext db = GetCurrentDbContext(); CacheChanges<T>(); db.Set<T>().Attach(entity); db.Entry<T>(entity).State = EntityState.Deleted; ; } public static Boolean Delete<T>(IQueryable<T> entities) where T : class { DbContext db = GetCurrentDbContext(); CacheChanges<T>(); db.Set<T>().RemoveRange(entities); ; } public static Boolean Delete<T>(Expression<Func<T, bool>> deleteWhere) where T : class { DbContext db = GetCurrentDbContext(); CacheChanges<T>(); IQueryable<T> entitys = GetIQuerybleByCache<T>().Where(deleteWhere); /** * change code 2017-5-6 11:11:19 qixiao * entitys.ForEach(m => db.Entry<T>(m).State = EntityState.Deleted); **/ entitys.ForEachAsync(m => db.Entry<T>(m).State = EntityState.Deleted); ; } #endregion #region Select public static Boolean Exist<T>(Expression<Func<T, Boolean>> selectWhere) where T : class { return GetIQuerybleByCache<T>().Where(selectWhere).FirstOrDefault<T>() == null ? false : true; } public static T selectSingle<T>(Expression<Func<T, Boolean>> selectWhere) where T : class { return GetIQuerybleByCache<T>().Where(selectWhere).FirstOrDefault<T>(); } public static IQueryable<T> selectAll<T>() where T : class { return GetIQuerybleByCache<T>(); } public static IQueryable<T> selectAll<T>(out int Count) where T : class { Count = GetIQuerybleByCache<T>().Count(); return GetIQuerybleByCache<T>(); } public static IQueryable<T> selectAll<T, TKey>(Expression<Func<T, TKey>> orderBy, Boolean isDESC = false) where T : class { if (isDESC) return GetIQuerybleByCache<T>().OrderByDescending(orderBy); else return GetIQuerybleByCache<T>().OrderBy(orderBy); } public static IQueryable<T> selectAll<T, TKey>(Expression<Func<T, TKey>> orderBy, out int Count, Boolean isDESC = false) where T : class { Count = GetIQuerybleByCache<T>().Count(); if (isDESC) return GetIQuerybleByCache<T>().OrderByDescending(orderBy); else return GetIQuerybleByCache<T>().OrderBy(orderBy); } public static IQueryable<T> selectAll<T>(Expression<Func<T, Boolean>> selectWhere) where T : class { return GetIQuerybleByCache<T>().Where(selectWhere); } public static IQueryable<T> selectAll<T>(Expression<Func<T, Boolean>> selectWhere, out int Count) where T : class { var IQueryable = GetIQuerybleByCache<T>().Where(selectWhere); Count = IQueryable.Count(); return IQueryable; } public static IQueryable<T> selectAll<T, TKey>(Expression<Func<T, TKey>> orderBy, Expression<Func<T, Boolean>> selectWhere, Boolean isDESC = false) where T : class { if (isDESC) return GetIQuerybleByCache<T>().Where(selectWhere).OrderByDescending(orderBy); else return GetIQuerybleByCache<T>().Where(selectWhere).OrderBy(orderBy); } public static IQueryable<T> selectAll<T, TKey>(Expression<Func<T, TKey>> orderBy, Expression<Func<T, Boolean>> selectWhere, out int Count, Boolean isDESC = false) where T : class { var IQueryable = GetIQuerybleByCache<T>().Where(selectWhere); Count = IQueryable.Count(); if (isDESC) return IQueryable.OrderByDescending(orderBy); else return IQueryable.OrderBy(orderBy); } public static IQueryable<T> selectAllPaging<T, TKey>(int pageIndex, int pageSize, Expression<Func<T, TKey>> orderBy, Boolean isDESC = false) where T : class { var IQueryable = GetIQuerybleByCache<T>(); if (isDESC) < ? : pageIndex - ) * (pageSize < ? : pageSize)).Take(pageSize < ? : pageSize); else < ? : pageIndex - ) * (pageSize < ? : pageSize)).Take(pageSize < ? : pageSize); } public static IQueryable<T> selectAllPaging<T, TKey>(int pageIndex, int pageSize, Expression<Func<T, TKey>> orderBy, out int Count, Boolean isDESC = false) where T : class { var IQueryable = GetIQuerybleByCache<T>(); Count = IQueryable.Count(); if (isDESC) < ? : pageIndex - ) * (pageSize < ? : pageSize)).Take(pageSize < ? : pageSize); else < ? : pageIndex - ) * (pageSize < ? : pageSize)).Take(pageSize < ? : pageSize); } public static IQueryable<T> selectAllPaging<T, TKey>(int pageIndex, int pageSize, Expression<Func<T, TKey>> orderBy, Expression<Func<T, Boolean>> selectWhere, Boolean isDESC = false) where T : class { var IQueryable = GetIQuerybleByCache<T>().Where(selectWhere); if (isDESC) < ? : pageIndex - ) * (pageSize < ? : pageSize)).Take(pageSize < ? : pageSize); else < ? : pageIndex - ) * (pageSize < ? : pageSize)).Take(pageSize < ? : pageSize); } public static IQueryable<T> selectAllPaging<T, TKey>(int pageIndex, int pageSize, Expression<Func<T, TKey>> orderBy, Expression<Func<T, Boolean>> selectWhere, out int Count, Boolean isDESC = false) where T : class { var IQueryable = GetIQuerybleByCache<T>().Where(selectWhere); Count = IQueryable.Count(); if (isDESC) < ? : pageIndex - ) * (pageSize < ? : pageSize)).Take(pageSize < ? : pageSize); else < ? : pageIndex - ) * (pageSize < ? : pageSize)).Take(pageSize < ? : pageSize); } #endregion #region Transaction public static void Transaction(Action action) { using (TransactionScope trans = new TransactionScope()) { action(); trans.Complete(); } } #endregion #region ExecuteSqlCommand public static void ExecuteSqlCommand(string sqlCommand) { DbContext db = GetCurrentDbContext(); db.Database.ExecuteSqlCommand(sqlCommand); } public static void ExecuteSqlCommand(string sqlCommand, params object[] parameters) { DbContext db = GetCurrentDbContext(); db.Database.ExecuteSqlCommand(sqlCommand, parameters); } #endregion } }
上述代码为当前版本的EF_Helper_DG代码,当然欢迎所有的同行们优化补充哦~
ORM框架 EF - code first 的封装 优化一的更多相关文章
- ORM框架 EF - code first 的封装
Code first 是Microsoft Entity Framework中的一种模式,CodeFirst不会有可视化的界面来进行拖动编辑DataBase-Entity,但会以一个类来进行对数据表关 ...
- ORM框架EF
应用程序和数据库采用Tcp协议通讯 ORM框架有: NHibernate ,Dapper ,Mybatis 底层是 ADO.Net 好处: 1.面向对象 2.没有sql减少学习成本,快速开发 3.编译 ...
- MVC系列学习(二)-初步了解ORM框架-EF
1.新建 一个控制台项目 2.添加一个数据项 a.选择数据库 注:数据库中的表如下: b.选择EF版本 c.选择表 3.初步了解EF框架 看到了多了一个以 edmx后缀的文件 在edmx文件上,右击打 ...
- ORM框架Hibernate (一) 对DAO封装和抽象
说明 前面已经给大家介绍了Struts这个框架,Struts是对Web项目的表示层进行了封装,而Hibernate是对Web项目中DAO层进行封装,也即是.NET中我们常用到的D层封装,即对访问数据库 ...
- 抛弃EF,20分构建一个属于自己的ORM框架
Poiuyt_cyc 博客园首页新随笔联系订阅管理随笔 - 11 文章 - 0 评论 - 111 抛弃EF,20分构建一个属于自己的ORM框架 相信EF大家都不陌生了,因为数据库表跟程序实体是一一 ...
- .Net 常用ORM框架对比:EF Core、FreeSql、SqlSuger
前言: 最近由于工作需要,需要选用一种ORM框架,也因此对EF Core.FreeSql.SqlSuger作简单对比.个人认为各有有优势,存在即合理,不然早就被淘汰了是吧,所以如何选择因人而议.因项目 ...
- 【EF 4】ORM框架及其流行产品之一EF介绍
导读:跳进了多租户切换数据库的坑,那么就继续走下去吧.在我们的项目中,是运用EF实现对数据库的操作,那么EF其实是.NET系统中,基于ORM框架的一个产品实现.在java那边,则有Hibernate和 ...
- webapi框架搭建-数据访问ef code first
webapi框架搭建系列博客 为什么用ef? 我相信很多博友和我一样都有这种“选择困难症”,我曾经有,现在也有,这是技术人的一个通病——总想用“更完美”的方式去实现,导致在技术选择上犹豫不决,或总是推 ...
- EF、Dapper、NHibernate等ORM框架的比较及优缺点
什么是ORM? ORM的全称是Object Relational Mapping,即对象关系映射.它的实现思想就是将关系数据库中表的数据映射成为对象,以对象的形式展现,这样开发人员就可以把对数据库的操 ...
随机推荐
- python3.6 +tkinter GUI编程 实现界面化的文本处理工具
更新: 2017.07.17 补充滚动条.win批处理拉起py 2017.08.13 新增自定义图标 --------原创 blogs: http://www.cnblogs.com/ ...
- 不同ios系统下mainscreen的applicationFrame和bounds值測试
打印结果(横屏,3.5寸.若4寸则最后一项对应添加) ios6: 2014-04-26 10:57:12.300 testAccount[18525:907] applicationFrame: {{ ...
- 诡异的 "password取回" 邮件问题
大部分系统中都有"找回password"的功能,我们的平台也做了此功能,用户可通过 短信,邮件 找回password. 当中对于邮件找回password的方式遇到奇特的问题.记录下 ...
- spool命令、创建一个表,创建而且copy表,查看别的用户下的表,rowid行地址 索引的时候使用,表的增删改查,删除表,oracle的回收站
1.spool命令 spool "D:\test.txt" spool off SQL> host cls 2.创建一个表 SQL> --条件(1):有创建 ...
- adb连接手机报错解决方案汇总(win7)
>>adb devices常见错误: >>解决方案汇总 检查端口是否占用:netstat -ano | findstr 5037 | findstr LISTENING 检 ...
- MongoDB 数据库备份与恢复
1.MongoDB数据库备份 1.语法: mongodump -h dbhost -d dbname -o dbdirectory 参数说明: ...
- Jquery对话框基本配置
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px "PingFang SC" } p.p2 { margin: 0.0px ...
- JAVA9模块化详解(二)——模块的使用
JAVA9模块化详解(二)--模块的使用 二.模块的使用 各自的模块可以在模块工件中定义,要么就是在编译期或者运行期嵌入的环境中.为了提供可靠的配置和强健的封装性,在分块的模块系统中利用他们,必须确定 ...
- 如何在VUE项目中添加ESLint
如何在VUE项目中添加ESLint 1. 首先在项目的根目录下 新建 .eslintrc.js文件,其配置规则可以如下:(自己小整理了一份),所有的代码如下: // https://eslint.or ...
- NYOJ-106 简单背包问题
首先观察题目,n表示输入数据的个数,s表示物品个数,m表示背包容重量,v表示物品单位重量的价值,w表示单个物品的总重量,物品可以分割,并且每个物品只可以拿一次,要求输出在满足包容重量的前提下包内物品价 ...