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 且在文章页面明显位置给出原文链接。
作者:
作者:
7tiny
Software Development
北京市海淀区 Haidian Area Beijing 100089,P.R.China
郵箱Email : seventiny@foxmail.com
網址Http: http://www.7tiny.com
WeChat: seven-tiny
更多联系方式点我哦~
Best Regard ~