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代码,当然欢迎所有的同行们优化补充哦~

 

posted @ 2017-05-25 10:05  7tiny  阅读(538)  评论(0编辑  收藏  举报