上一节我们讲到对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 的封装 优化一的更多相关文章

  1. ORM框架 EF - code first 的封装

    Code first 是Microsoft Entity Framework中的一种模式,CodeFirst不会有可视化的界面来进行拖动编辑DataBase-Entity,但会以一个类来进行对数据表关 ...

  2. ORM框架EF

    应用程序和数据库采用Tcp协议通讯 ORM框架有: NHibernate ,Dapper ,Mybatis 底层是 ADO.Net 好处: 1.面向对象 2.没有sql减少学习成本,快速开发 3.编译 ...

  3. MVC系列学习(二)-初步了解ORM框架-EF

    1.新建 一个控制台项目 2.添加一个数据项 a.选择数据库 注:数据库中的表如下: b.选择EF版本 c.选择表 3.初步了解EF框架 看到了多了一个以 edmx后缀的文件 在edmx文件上,右击打 ...

  4. ORM框架Hibernate (一) 对DAO封装和抽象

    说明 前面已经给大家介绍了Struts这个框架,Struts是对Web项目的表示层进行了封装,而Hibernate是对Web项目中DAO层进行封装,也即是.NET中我们常用到的D层封装,即对访问数据库 ...

  5. 抛弃EF,20分构建一个属于自己的ORM框架

    Poiuyt_cyc 博客园首页新随笔联系订阅管理随笔 - 11  文章 - 0  评论 - 111 抛弃EF,20分构建一个属于自己的ORM框架 相信EF大家都不陌生了,因为数据库表跟程序实体是一一 ...

  6. .Net 常用ORM框架对比:EF Core、FreeSql、SqlSuger

    前言: 最近由于工作需要,需要选用一种ORM框架,也因此对EF Core.FreeSql.SqlSuger作简单对比.个人认为各有有优势,存在即合理,不然早就被淘汰了是吧,所以如何选择因人而议.因项目 ...

  7. 【EF 4】ORM框架及其流行产品之一EF介绍

    导读:跳进了多租户切换数据库的坑,那么就继续走下去吧.在我们的项目中,是运用EF实现对数据库的操作,那么EF其实是.NET系统中,基于ORM框架的一个产品实现.在java那边,则有Hibernate和 ...

  8. webapi框架搭建-数据访问ef code first

    webapi框架搭建系列博客 为什么用ef? 我相信很多博友和我一样都有这种“选择困难症”,我曾经有,现在也有,这是技术人的一个通病——总想用“更完美”的方式去实现,导致在技术选择上犹豫不决,或总是推 ...

  9. EF、Dapper、NHibernate等ORM框架的比较及优缺点

    什么是ORM? ORM的全称是Object Relational Mapping,即对象关系映射.它的实现思想就是将关系数据库中表的数据映射成为对象,以对象的形式展现,这样开发人员就可以把对数据库的操 ...

随机推荐

  1. 命令行保存指定目录文件的名字(可包含文件夹文字)到txt文本文件

    Microsoft Visual Studio中配置OpenCV解决方案属性的时候, 需要将OpenCV的lib扩展名的库文件添加到属性的依赖列表里面,网上的有些人博客里面直接给出的会有问题(但大多数 ...

  2. DEBUG技巧-设定合适的日志级别

    有些技能只有踩过坑的人才能够掌握,能用来避免后来的坑,很多时候是用凌晨的时间换来的,我们通常把他叫做经验. 故事 这个一个关于springmvc的坑的故事. 某天晚上本打算一个小功能分分钟搞定上线,但 ...

  3. javaWeb中URLEncoder.encode空格问题

    近期开发一个在线坐席的功能.发现推送的消息中空格变成了+ .查询发现URLEncoder.encode的问题.曾经用的时候也没注意过,解决的方法网上是对URLEncoder.encode的之后的字符串 ...

  4. 刚在在win8.1下装了ubuntu12.04

    这是一个開始. 開始我想在win7下,由于我本来是7和win8.1双系统,想直接把win7覆盖了. 可是不知道怎么回事,比較复杂.于是在win8.1下装了. 先把win7的系统盘格式化了. 把下的is ...

  5. 微信小程序的Web API接口设计及常见接口实现

    微信小程序给我们提供了一个很好的开发平台,可以用于展现各种数据和实现丰富的功能,通过小程序的请求Web API 平台获取JSON数据后,可以在小程序界面上进行数据的动态展示.在数据的关键 一环中,我们 ...

  6. mac brew install nginx遇到的坑

    默认使用 brew install nginx 出现了一下的错误: p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: ...

  7. [UWP]了解TypeConverter

    1. 前言 TypeConverter是XAML解释器的幕后功臣,它做了大量工作,从WPF诞生以来,几乎每一次XAML的运作都有它的参与.虽然UWP中TypeConverter已经彻彻底底退居幕后,连 ...

  8. 在Windows上运行Spark程序

    一.下载Saprk程序 https://d3kbcqa49mib13.cloudfront.net/spark-2.1.1-bin-hadoop2.7.tgz 解压到d:\spark-2.1.1-bi ...

  9. 原生JS的Ajax

    转自:https://www.cnblogs.com/yufann/p/JS-Ajax.html 1.创建一个Ajax对象 非IE6浏览器:var obj = new XMLHttpReuqest() ...

  10. JAVA NIO学习一:NIO简介、NIO&IO的主要区别

    在前面学习了IO之后,今天我们开始进入NIO学习环节,首先我们会NIO做一个简单的介绍,让大家认识NIO,然后会和IO进行一个对比认识进行区分.好了,下面我们就开始学习: 一.NIO简介 1.概述 从 ...