上一节我们讲到对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. Loadrunner 中时间戳函数 web_save_timestamp_param(时间返回数值)

    web_save_timestamp_param("tStamp", LAST); lr_output_message("Moon1:%s",lr_eval_s ...

  2. android.app.Activity 的介绍

    发现当前Android的资料不是非常多,并且对于Activity的介绍也非常少.所以把官方文档的android.app.Activity的介绍翻译了一下,增加了一些自己的理解.各位假设认为我自己理解的 ...

  3. vector删除元素与清除内存空洞

    问题:stl中的vector容器经常造成删除假象,这对于c++程序猿来说是极其讨厌的,<effective stl>大师已经将之列为第17条,使用交换技巧来修整过剩容量. 内存空洞这个名词 ...

  4. 解决 ASP.NET Core MySql varchar 字符串截取(长度 255)

    ASP.NET Core 中使用 MySql,如果字段类型为varchar,不管设置多少长度,插入或更新数据的时候,会自动截断(截取 255 长度的字符). 出现问题的原因,就是使用了MySql.Da ...

  5. IEEE Trans 2007 Signal Recovery From Random Measurements via OMP

    看了一篇IEEE Trans上的关于CS图像重构的OMP算法的文章,大部分..看不懂,之前在看博客的时候对流程中的一些标号看不太懂,看完论文之后对流程有了一定的了解,所以在这里解释一下流程,其余的如果 ...

  6. 在用python操作mysql时报错:ModuleNotFoundError: No module named 'MySQLdb'

    用Flask+python+mysql写一个小项目 系统 win10 py版本:3.6.1 在配置数据库时报错ModuleNotFoundError: No module named 'MySQLdb ...

  7. 关于postgres中的一些宏的tips

    Postgresql作为C语言开发的代码,其中大量的运用了一些宏的操作. 因此理解这些宏很重要,然而有时候这些宏总让人很费解. 作为一个经常翻翻postgresql源码的小白,在这里做一个记录吧,方便 ...

  8. Laravel学习笔记(一)

         根据国外的调查,Laravel是最流行的框架,最近公司需要PHP的开发人员,但是一直招不到人,只好亲自上阵研究一下.由于以前对PHP只是大致了解,这次学习开始的时候也挺挠头的,到今天稍微入了 ...

  9. 教程:安装禅道zentao项目管理软件github上的开发版

    该文章转自:吕滔博客 直接从github拉下来的禅道的源码,是跑不起来的.除非你按我的教程来做...哈哈哈(不要脸)~~~~ 禅道官网提供的版本包是带了有安装文件,并有打包合成一些css.js文件的. ...

  10. 在 ReactNative 的 App 中,集成 Bugly 你会遇到的一些坑

    一.前言 最近开新项目,准备尝试一下 ReactNative,所以前期做了一些调研工作,ReactNative 的优点非常的明显,可以做到跨平台,除了少部分 UI 效果可能需要对不同的平台进行单独适配 ...