zoukankan      html  css  js  c++  java
  • ORM框架 EF code first 的封装 优化一

    上一节我们讲到对EF(EntityFramework)的初步封装,任何事情都不可能一蹴而就,通过大量的实际项目的实战,也发现了其中的各种问题。在这一章中,我们对上一章的EF_Helper_DG进行优化,主要优化点如下:

    1.由DB实体单例模式改为从缓存中获取;

    2.加入服务器缓存,协助查询,提升查询性能;

    3.优化CUD操作方法的执行方式;

    下面直接展示新的EF_Helper_DG 代码:

      1 using LinqKit; //AsExpandable() in linqkit.dll
      2 using System;
      3 using System.Linq;
      4 using System.Linq.Expressions;
      5 using System.Data.Entity;
      6 using System.Transactions;
      7 using QX_Frame.Helper_DG.Configs;
      8 
      9 namespace QX_Frame.Helper_DG
     10 {
     11     /*  time:   2016-10-30 15:26:05
     12         author: qixiao
     13     */
     14     /// <summary>
     15     /// EntityFramework CodeFirst Helper 
     16     /// </summary>
     17     /// <typeparam name="Db">DbContext</typeparam>
     18     public abstract class EF_Helper_DG<Db> where Db : DbContext
     19     {
     20         /*the singleton Db */
     21         //private volatile static Db db = null;   //volatile find Db in memory not in cache
     22 
     23         #region The Singleton to new DBEntity_DG
     24 
     25         //private static readonly object lockHelper = new object();
     26         //static EF_Helper_DG()
     27         //{
     28         //    if (db == null)
     29         //    {
     30         //        lock (lockHelper)
     31         //        {
     32         //            if (db == null)
     33         //                db = System.Activator.CreateInstance<Db>();
     34         //        }
     35         //    }
     36 
     37         //    //close the Validate of EF OnSaveEnabled
     38         //    db.Configuration.ValidateOnSaveEnabled = false;
     39         //}
     40 
     41         #endregion
     42 
     43         #region get current dbContext
     44         public static DbContext GetCurrentDbContext()
     45         {
     46             //method 1 : CallContext 该方法有有时候第一次访问不到的bug
     47             //CallContext:是线程内部唯一的独用的数据槽(一块内存空间)  
     48             //Db dbContext = CallContext.GetData("DbContext") as Db;
     49             //if (dbContext == null)  //线程在内存中没有此上下文  
     50             //{
     51             //    //create a dbContext to memory if dbContext has not exist
     52             //    dbContext = System.Activator.CreateInstance<Db>();
     53             //    CallContext.SetData("DbContext", dbContext);
     54             //}
     55 
     56             //method 2 :
     57             Db dbContext = Cache_Helper_DG.Cache_Get("dbContext") as Db;
     58             if (dbContext == null)
     59             {
     60                 //create a dbContext to memory if dbContext has not exist
     61                 dbContext = System.Activator.CreateInstance<Db>();
     62                 Cache_Helper_DG.Cache_Add("dbContext",dbContext);
     63             }
     64             return dbContext;
     65         }
     66         #endregion
     67 
     68         #region Cache Strategy
     69 
     70         /// <summary>
     71         /// edit data cache must update
     72         /// </summary>
     73         public static void CacheChanges<T>()
     74         {
     75             if (QX_Frame_Helper_DG_Config.Cache_IsCache)
     76             {
     77                 Cache_Helper_DG.Cache_Delete(nameof(T));
     78             }
     79         }
     80 
     81         /// <summary>
     82         /// query cache
     83         /// </summary>
     84         /// <typeparam name="T"></typeparam>
     85         /// <returns></returns>
     86         public static IQueryable<T> GetIQuerybleByCache<T>() where T : class
     87         {
     88             if (QX_Frame_Helper_DG_Config.Cache_IsCache)
     89             {
     90                 IQueryable<T> iqueryable = Cache_Helper_DG.Cache_Get(nameof(T)) as IQueryable<T>;
     91                 if (iqueryable == null)
     92                 {
     93                     DbContext db = GetCurrentDbContext();
     94                     iqueryable = db.Set<T>().AsExpandable();
     95                     Cache_Helper_DG.Cache_Add(nameof(T), iqueryable, null, DateTime.Now.AddMinutes(QX_Frame_Helper_DG_Config.Cache_CacheExpirationTime_Minutes), TimeSpan.Zero);
     96                 }
     97                 return iqueryable;
     98             }
     99             else
    100             {
    101                 DbContext db = GetCurrentDbContext();
    102                 return db.Set<T>().AsExpandable();
    103             }
    104         }
    105 
    106         #endregion
    107 
    108         #region Add 
    109 
    110         public static Boolean Add<T>(T entity) where T : class
    111         {
    112             DbContext db = GetCurrentDbContext();
    113             CacheChanges<T>();
    114             db.Entry<T>(entity).State = EntityState.Added;
    115             return db.SaveChanges() > 0;
    116         }
    117         public static Boolean Add<T>(T entity, out T outEntity) where T : class
    118         {
    119             DbContext db = GetCurrentDbContext();
    120             CacheChanges<T>();
    121             db.Entry<T>(entity).State = EntityState.Added;
    122             outEntity = entity;
    123             return db.SaveChanges() > 0;
    124         }
    125         public static Boolean Add<T>(IQueryable<T> entities) where T : class
    126         {
    127             DbContext db = GetCurrentDbContext();
    128             CacheChanges<T>();
    129             db.Set<T>().AddRange(entities);
    130             return db.SaveChanges() > 0;
    131         }
    132 
    133         #endregion
    134 
    135         #region Update
    136 
    137         public static Boolean Update<T>(T entity) where T : class
    138         {
    139             DbContext db = GetCurrentDbContext();
    140             CacheChanges<T>();
    141             if (db.Entry<T>(entity).State == EntityState.Detached)
    142             {
    143                 db.Set<T>().Attach(entity);
    144                 db.Entry<T>(entity).State = EntityState.Modified;
    145             }
    146             else
    147             {
    148                 db.SaveChanges();
    149                 return true;
    150             }
    151             return db.SaveChanges() > 0;
    152         }
    153         public static Boolean Update<T>(T entity, out T outEntity) where T : class
    154         {
    155             DbContext db = GetCurrentDbContext();
    156             CacheChanges<T>();
    157             outEntity = entity;
    158             if (db.Entry<T>(entity).State == EntityState.Detached)
    159             {
    160                 db.Set<T>().Attach(entity);
    161                 db.Entry<T>(entity).State = EntityState.Modified;
    162             }
    163             else
    164             {
    165                 db.SaveChanges();
    166                 return true;
    167             }
    168             return db.SaveChanges() > 0;
    169         }
    170         #endregion
    171 
    172         #region Delete
    173 
    174         public static Boolean Delete<T>(T entity) where T : class
    175         {
    176             DbContext db = GetCurrentDbContext();
    177             CacheChanges<T>();
    178             db.Set<T>().Attach(entity);
    179             db.Entry<T>(entity).State = EntityState.Deleted;
    180             return db.SaveChanges() > 0;
    181         }
    182         public static Boolean Delete<T>(IQueryable<T> entities) where T : class
    183         {
    184             DbContext db = GetCurrentDbContext();
    185             CacheChanges<T>();
    186             db.Set<T>().RemoveRange(entities);
    187             return db.SaveChanges() > 0;
    188         }
    189         public static Boolean Delete<T>(Expression<Func<T, bool>> deleteWhere) where T : class
    190         {
    191             DbContext db = GetCurrentDbContext();
    192             CacheChanges<T>();
    193             IQueryable<T> entitys = GetIQuerybleByCache<T>().Where(deleteWhere);
    194             /**
    195              * change code 2017-5-6 11:11:19 qixiao
    196              * entitys.ForEach(m => db.Entry<T>(m).State = EntityState.Deleted);
    197              **/
    198             entitys.ForEachAsync(m => db.Entry<T>(m).State = EntityState.Deleted);
    199             return db.SaveChanges() > 0;
    200         }
    201         #endregion
    202 
    203         #region Select 
    204 
    205         public static Boolean Exist<T>(Expression<Func<T, Boolean>> selectWhere) where T : class
    206 
    207         {
    208             return GetIQuerybleByCache<T>().Where(selectWhere).FirstOrDefault<T>() == null ? false : true;
    209         }
    210         public static T selectSingle<T>(Expression<Func<T, Boolean>> selectWhere) where T : class
    211         {
    212             return GetIQuerybleByCache<T>().Where(selectWhere).FirstOrDefault<T>();
    213         }
    214         public static IQueryable<T> selectAll<T>() where T : class
    215         {
    216             return GetIQuerybleByCache<T>();
    217         }
    218         public static IQueryable<T> selectAll<T>(out int Count) where T : class
    219         {
    220             Count = GetIQuerybleByCache<T>().Count();
    221             return GetIQuerybleByCache<T>();
    222         }
    223         public static IQueryable<T> selectAll<T, TKey>(Expression<Func<T, TKey>> orderBy, Boolean isDESC = false) where T : class
    224         {
    225             if (isDESC)
    226                 return GetIQuerybleByCache<T>().OrderByDescending(orderBy);
    227             else
    228                 return GetIQuerybleByCache<T>().OrderBy(orderBy);
    229         }
    230         public static IQueryable<T> selectAll<T, TKey>(Expression<Func<T, TKey>> orderBy, out int Count, Boolean isDESC = false) where T : class
    231         {
    232             Count = GetIQuerybleByCache<T>().Count();
    233             if (isDESC)
    234                 return GetIQuerybleByCache<T>().OrderByDescending(orderBy);
    235             else
    236                 return GetIQuerybleByCache<T>().OrderBy(orderBy);
    237         }
    238         public static IQueryable<T> selectAll<T>(Expression<Func<T, Boolean>> selectWhere) where T : class
    239         {
    240             return GetIQuerybleByCache<T>().Where(selectWhere);
    241         }
    242         public static IQueryable<T> selectAll<T>(Expression<Func<T, Boolean>> selectWhere, out int Count) where T : class
    243         {
    244             var IQueryable = GetIQuerybleByCache<T>().Where(selectWhere);
    245             Count = IQueryable.Count();
    246             return IQueryable;
    247         }
    248         public static IQueryable<T> selectAll<T, TKey>(Expression<Func<T, TKey>> orderBy, Expression<Func<T, Boolean>> selectWhere, Boolean isDESC = false) where T : class
    249         {
    250             if (isDESC)
    251                 return GetIQuerybleByCache<T>().Where(selectWhere).OrderByDescending(orderBy);
    252             else
    253                 return GetIQuerybleByCache<T>().Where(selectWhere).OrderBy(orderBy);
    254         }
    255         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
    256         {
    257             var IQueryable = GetIQuerybleByCache<T>().Where(selectWhere);
    258             Count = IQueryable.Count();
    259             if (isDESC)
    260                 return IQueryable.OrderByDescending(orderBy);
    261             else
    262                 return IQueryable.OrderBy(orderBy);
    263         }
    264 
    265         public static IQueryable<T> selectAllPaging<T, TKey>(int pageIndex, int pageSize, Expression<Func<T, TKey>> orderBy, Boolean isDESC = false) where T : class
    266         {
    267             var IQueryable = GetIQuerybleByCache<T>();
    268             if (isDESC)
    269                 return IQueryable.OrderByDescending(orderBy).Skip((pageIndex - 1 < 0 ? 0 : pageIndex - 1) * (pageSize < 0 ? 0 : pageSize)).Take(pageSize < 0 ? 0 : pageSize);
    270             else
    271                 return IQueryable.OrderBy(orderBy).Skip((pageIndex - 1 < 0 ? 0 : pageIndex - 1) * (pageSize < 0 ? 0 : pageSize)).Take(pageSize < 0 ? 0 : pageSize);
    272         }
    273         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
    274         {
    275             var IQueryable = GetIQuerybleByCache<T>();
    276             Count = IQueryable.Count();
    277             if (isDESC)
    278                 return IQueryable.OrderByDescending(orderBy).Skip((pageIndex - 1 < 0 ? 0 : pageIndex - 1) * (pageSize < 0 ? 0 : pageSize)).Take(pageSize < 0 ? 0 : pageSize);
    279             else
    280                 return IQueryable.OrderBy(orderBy).Skip((pageIndex - 1 < 0 ? 0 : pageIndex - 1) * (pageSize < 0 ? 0 : pageSize)).Take(pageSize < 0 ? 0 : pageSize);
    281         }
    282         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
    283         {
    284             var IQueryable = GetIQuerybleByCache<T>().Where(selectWhere);
    285             if (isDESC)
    286                 return IQueryable.OrderByDescending(orderBy).Skip((pageIndex - 1 < 0 ? 0 : pageIndex - 1) * (pageSize < 0 ? 0 : pageSize)).Take(pageSize < 0 ? 0 : pageSize);
    287             else
    288                 return IQueryable.OrderBy(orderBy).Skip((pageIndex - 1 < 0 ? 0 : pageIndex - 1) * (pageSize < 0 ? 0 : pageSize)).Take(pageSize < 0 ? 0 : pageSize);
    289         }
    290         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
    291         {
    292             var IQueryable = GetIQuerybleByCache<T>().Where(selectWhere);
    293             Count = IQueryable.Count();
    294             if (isDESC)
    295                 return IQueryable.OrderByDescending(orderBy).Skip((pageIndex - 1 < 0 ? 0 : pageIndex - 1) * (pageSize < 0 ? 0 : pageSize)).Take(pageSize < 0 ? 0 : pageSize);
    296             else
    297                 return IQueryable.OrderBy(orderBy).Skip((pageIndex - 1 < 0 ? 0 : pageIndex - 1) * (pageSize < 0 ? 0 : pageSize)).Take(pageSize < 0 ? 0 : pageSize);
    298         }
    299 
    300         #endregion
    301 
    302         #region Transaction
    303         public static void Transaction(Action action)
    304         {
    305             using (TransactionScope trans = new TransactionScope())
    306             {
    307                 action();
    308                 trans.Complete();
    309             }
    310         }
    311         #endregion
    312 
    313         #region ExecuteSqlCommand
    314 
    315         public static void ExecuteSqlCommand(string sqlCommand)
    316         {
    317             DbContext db = GetCurrentDbContext();
    318             db.Database.ExecuteSqlCommand(sqlCommand);
    319         }
    320         public static void ExecuteSqlCommand(string sqlCommand, params object[] parameters)
    321         {
    322             DbContext db = GetCurrentDbContext();
    323             db.Database.ExecuteSqlCommand(sqlCommand, parameters);
    324         }
    325 
    326         #endregion
    327     }
    328 }

    上述代码为当前版本的EF_Helper_DG代码,当然欢迎所有的同行们优化补充哦~

    本文为七小站主原创作品,转载请注明出处:http://www.cnblogs.com/7tiny/ 且在文章页面明显位置给出原文链接。

    作者信息(详情):

    QiXiao_柒小(東)
    Software Development
    北京市海淀区 Haidian Area Beijing 100089,P.R.China
    郵箱Email : seventiny@foxmail.com  
    網址Http: http://www.7tiny.com
    QQ:1124999434 , WeChat: wd8622088 (尽量加微信)
    (专好结交天下英雄好汉,可聊天,可谈技,可约饭,可..嗯,原则是要有的~) 更多联系方式点我哦~


    Best Regard ~
  • 相关阅读:
    升级2010
    如何修改MSSQL的用户名
    减小delphi体积的方法
    Delphi调用大漠插件示例
    Delphi 7升级到XE2的字符串问题
    MSSQL 清空数据库中表的数据
    MSSQL 2008 密钥
    springboot 2.1.4 多数据源配置
    springboot 数据库连接 解决驼峰命名问题
    Flask 热更新
  • 原文地址:https://www.cnblogs.com/7tiny/p/6902262.html
Copyright © 2011-2022 走看看