ORM框架 EF - code first 的封装 优化一
上一节我们讲到对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 的封装 优化一的更多相关文章
- ORM框架 EF - code first 的封装
Code first 是Microsoft Entity Framework中的一种模式,CodeFirst不会有可视化的界面来进行拖动编辑DataBase-Entity,但会以一个类来进行对数据表关 ...
- ORM框架EF
应用程序和数据库采用Tcp协议通讯 ORM框架有: NHibernate ,Dapper ,Mybatis 底层是 ADO.Net 好处: 1.面向对象 2.没有sql减少学习成本,快速开发 3.编译 ...
- MVC系列学习(二)-初步了解ORM框架-EF
1.新建 一个控制台项目 2.添加一个数据项 a.选择数据库 注:数据库中的表如下: b.选择EF版本 c.选择表 3.初步了解EF框架 看到了多了一个以 edmx后缀的文件 在edmx文件上,右击打 ...
- ORM框架Hibernate (一) 对DAO封装和抽象
说明 前面已经给大家介绍了Struts这个框架,Struts是对Web项目的表示层进行了封装,而Hibernate是对Web项目中DAO层进行封装,也即是.NET中我们常用到的D层封装,即对访问数据库 ...
- 抛弃EF,20分构建一个属于自己的ORM框架
Poiuyt_cyc 博客园首页新随笔联系订阅管理随笔 - 11 文章 - 0 评论 - 111 抛弃EF,20分构建一个属于自己的ORM框架 相信EF大家都不陌生了,因为数据库表跟程序实体是一一 ...
- .Net 常用ORM框架对比:EF Core、FreeSql、SqlSuger
前言: 最近由于工作需要,需要选用一种ORM框架,也因此对EF Core.FreeSql.SqlSuger作简单对比.个人认为各有有优势,存在即合理,不然早就被淘汰了是吧,所以如何选择因人而议.因项目 ...
- 【EF 4】ORM框架及其流行产品之一EF介绍
导读:跳进了多租户切换数据库的坑,那么就继续走下去吧.在我们的项目中,是运用EF实现对数据库的操作,那么EF其实是.NET系统中,基于ORM框架的一个产品实现.在java那边,则有Hibernate和 ...
- webapi框架搭建-数据访问ef code first
webapi框架搭建系列博客 为什么用ef? 我相信很多博友和我一样都有这种“选择困难症”,我曾经有,现在也有,这是技术人的一个通病——总想用“更完美”的方式去实现,导致在技术选择上犹豫不决,或总是推 ...
- EF、Dapper、NHibernate等ORM框架的比较及优缺点
什么是ORM? ORM的全称是Object Relational Mapping,即对象关系映射.它的实现思想就是将关系数据库中表的数据映射成为对象,以对象的形式展现,这样开发人员就可以把对数据库的操 ...
随机推荐
- archsummit2017见闻和思考
前几天参加了archsummit的北京站.2天的日程安排的十分紧凑,大多数时间同时有多场专题分享,选择想要听的专题就成了首要的事情,按照感兴趣的,可能用到的,启发思考的原则选择了几场适合自己的专题,这 ...
- KNN K~近邻算法笔记
K~近邻算法是最简单的机器学习算法.工作原理就是:将新数据的每一个特征与样本集中数据相应的特征进行比較.然后算法提取样本集中特征最相似的数据的分类标签.一般来说.仅仅提取样本数据集中前K个最相似的数据 ...
- UVA - 10249 The Grand Dinner
Description Problem D The Grand Dinner Input: standard input Output: standard output Time Limit: 15 ...
- SharePoint Patterns and Practices 简介
作者:陈希章 发表于 2017年12月22日 SharePoint Patterns and Practices,以下简称PnP,是由微软的SharePoint产品组发起并主持的一个有关SharePo ...
- springboot 热部署 idea版本(转)
spring为开发者提供了一个名为spring-boot-devtools的模块来使Spring Boot应用支持热部署,提高开发者的开发效率,无需手动重启Spring Boot应用. devtool ...
- Jmeter接口测试使用beanshell断言json返回
一般情况下响应断言就能解决很多问题,但是返回复杂的json时就需要用到beanshell断言. 举个例子 免费的接口API www.sojson.com/api/beian/sojson.com ho ...
- 数值函数ROUND(四舍五入),TRUNC(不四舍五入),MOD
- 用C#写入Excel表并保存
想用C#操作Excel表,首先要做一些准备工作. 如果要操作 microsoft office Excel 2003表,就需要引入Microsoft office 11.0 object librar ...
- C:数据结构与算法之单链表
单链表相对于顺序表比较难理解,但是比较实用,单链表的插入,删除不需要移动数据元素,只需要一个指针来寻找所需要的元素,还有一个大优点就是不浪费空间,当你想要增加一个结点可以申请(malloc())一个结 ...
- C++ 头文件系列(ostream)
1. 简介 头文件ostream主要定义了一个输出流类模版basic_ostream,该模版继承自basic_ios模版. 2. basic_ostream模版 2.1 sentry类 与basic_ ...