一. 简介

  该章节,可以说是一个简单轻松的章节,只要你对Expression表达式树、EF的基本使用、泛型有所了解,那么本章节实质上就是一个非常简单的封装章节,便于我们快捷开发。

 PS:在该章节对于EF的上下文怎么处理,怎么来的,不做介绍,在后续的框架篇将详细介绍,下面的EF上下文,将直接使用db代替。

 如果你对Expression、EF的增删改查、泛型生疏的话,可以先阅读以下章节:

  (1). Expression表达式目录树:http://www.cnblogs.com/yaopengfei/p/7486870.html

  (2). EF的基本增删改查:http://www.cnblogs.com/yaopengfei/p/7674715.html

  (3). 泛型的使用:http://www.cnblogs.com/yaopengfei/p/6880629.html

二. 代码封装分享

  下面的代码封装,主要就是围绕EF的增删改查进行封装以及各自对应的扩展,其中包括事务一体的封装、事务分离的封装、集成 Z.EntityFramework.Extensions 插件的封装、以及EF调用SQL语句的封装。

1. EF调用SQL语句:

         /// <summary>
/// 执行增加,删除,修改操作(或调用存储过程)
/// </summary>
/// <param name="sql"></param>
/// <param name="pars"></param>
/// <returns></returns>
public int ExecuteSql(string sql, params SqlParameter[] pars)
{
return db.Database.ExecuteSqlCommand(sql, pars);
} /// <summary>
/// 执行查询操作
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sql"></param>
/// <param name="pars"></param>
/// <returns></returns>
public List<T> ExecuteQuery<T>(string sql, params SqlParameter[] pars)
{
return db.Database.SqlQuery<T>(sql, pars).ToList();
}

2. EF增删改查封装(事务一体)

 (1). 新增

   public int Add(T model)
{
DbSet<T> dst = db.Set<T>();
dst.Add(model);
return db.SaveChanges();
}

(2). 删除

         /// <summary>
/// 删除(适用于先查询后删除的单个实体)
/// </summary>
/// <param name="model">需要删除的实体</param>
/// <returns></returns>
public int Del(T model)
{
db.Set<T>().Attach(model);
db.Set<T>().Remove(model);
return db.SaveChanges();
}
/// <summary>
/// 根据条件删除(支持批量删除)
/// </summary>
/// <param name="delWhere">传入Lambda表达式(生成表达式目录树)</param>
/// <returns></returns>
public int DelBy(Expression<Func<T, bool>> delWhere)
{
List<T> listDels = db.Set<T>().Where(delWhere).ToList();
listDels.ForEach(d =>
{
db.Set<T>().Attach(d);
db.Set<T>().Remove(d);
});
return db.SaveChanges();
}

(3). 查询

         /// <summary>
/// 根据条件查询
/// </summary>
/// <param name="whereLambda">查询条件(lambda表达式的形式生成表达式目录树)</param>
/// <returns></returns>
public List<T> GetListBy(Expression<Func<T, bool>> whereLambda)
{
return db.Set<T>().Where(whereLambda).ToList();
}
/// <summary>
/// 根据条件排序和查询
/// </summary>
/// <typeparam name="Tkey">排序字段类型</typeparam>
/// <param name="whereLambda">查询条件</param>
/// <param name="orderLambda">排序条件</param>
/// <param name="isAsc">升序or降序</param>
/// <returns></returns>
public List<T> GetListBy<Tkey>(Expression<Func<T, bool>> whereLambda, Expression<Func<T, Tkey>> orderLambda, bool isAsc = true)
{
List<T> list = null;
if (isAsc)
{
list = db.Set<T>().Where(whereLambda).OrderBy(orderLambda).ToList();
}
else
{
list = db.Set<T>().Where(whereLambda).OrderByDescending(orderLambda).ToList();
}
return list;
}
/// <summary>
/// 分页查询
/// </summary>
/// <typeparam name="Tkey">排序字段类型</typeparam>
/// <param name="pageIndex">页码</param>
/// <param name="pageSize">页容量</param>
/// <param name="whereLambda">查询条件</param>
/// <param name="orderLambda">排序条件</param>
/// <param name="isAsc">升序or降序</param>
/// <returns></returns>
public List<T> GetPageList<Tkey>(int pageIndex, int pageSize, Expression<Func<T, bool>> whereLambda, Expression<Func<T, Tkey>> orderLambda, bool isAsc = true)
{ List<T> list = null;
if (isAsc)
{
list = db.Set<T>().Where(whereLambda).OrderBy(orderLambda)
.Skip((pageIndex - ) * pageSize).Take(pageSize).ToList();
}
else
{
list = db.Set<T>().Where(whereLambda).OrderByDescending(orderLambda)
.Skip((pageIndex - ) * pageSize).Take(pageSize).ToList();
}
return list;
}
/// <summary>
/// 分页查询输出总行数
/// </summary>
/// <typeparam name="Tkey">排序字段类型</typeparam>
/// <param name="pageIndex">页码</param>
/// <param name="pageSize">页容量</param>
/// <param name="whereLambda">查询条件</param>
/// <param name="orderLambda">排序条件</param>
/// <param name="isAsc">升序or降序</param>
/// <returns></returns>
public List<T> GetPageList<Tkey>(int pageIndex, int pageSize, ref int rowCount, Expression<Func<T, bool>> whereLambda, Expression<Func<T, Tkey>> orderLambda, bool isAsc = true)
{
int count = ;
List<T> list = null;
count = db.Set<T>().Where(whereLambda).Count();
if (isAsc)
{
var iQueryList = db.Set<T>().Where(whereLambda).OrderBy(orderLambda)
.Skip((pageIndex - ) * pageSize).Take(pageSize); list = iQueryList.ToList();
}
else
{
var iQueryList = db.Set<T>().Where(whereLambda).OrderByDescending(orderLambda)
.Skip((pageIndex - ) * pageSize).Take(pageSize);
list = iQueryList.ToList();
}
rowCount = count;
return list;
}

(4). 修改

         /// <summary>
/// 修改
/// </summary>
/// <param name="model">修改后的实体</param>
/// <returns></returns>
public int Modify(T model)
{
db.Entry(model).State = EntityState.Modified;
return db.SaveChanges();
} /// <summary>
/// 单实体扩展修改(把不需要修改的列用LAMBDA数组表示出来)
/// </summary>
/// <param name="model">要修改的实体对象</param>
/// <param name="ignoreProperties">不须要修改的相关字段</param>
/// <returns>受影响的行数</returns>
public int Modify(T model, params Expression<Func<T, object>>[] ignoreProperties)
{
using (DbContext db = new DBContextFactory().GetDbContext())
{
db.Set<T>().Attach(model); DbEntityEntry entry = db.Entry<T>(model);
entry.State = EntityState.Unchanged; Type t = typeof(T);
List<PropertyInfo> proInfos = t.GetProperties(BindingFlags.Instance | BindingFlags.Public).ToList(); Dictionary<string, PropertyInfo> dicPros = new Dictionary<string, PropertyInfo>();
proInfos.ForEach(
p => dicPros.Add(p.Name, p)
); if (ignoreProperties != null)
{
foreach (var ignorePropertyExpression in ignoreProperties)
{
//根据表达式得到对应的字段信息
var ignorePropertyName = new PropertyExpressionParser<T>(ignorePropertyExpression).Name;
dicPros.Remove(ignorePropertyName);
}
} foreach (string proName in dicPros.Keys)
{
entry.Property(proName).IsModified = true;
}
return db.SaveChanges();
}
} /// <summary>
/// 批量修改(非lambda)
/// </summary>
/// <param name="model">要修改实体中 修改后的属性 </param>
/// <param name="whereLambda">查询实体的条件</param>
/// <param name="proNames">lambda的形式表示要修改的实体属性名</param>
/// <returns></returns>
public int ModifyBy(T model, Expression<Func<T, bool>> whereLambda, params string[] proNames)
{
List<T> listModifes = db.Set<T>().Where(whereLambda).ToList();
Type t = typeof(T);
List<PropertyInfo> proInfos = t.GetProperties(BindingFlags.Instance | BindingFlags.Public).ToList();
Dictionary<string, PropertyInfo> dicPros = new Dictionary<string, PropertyInfo>();
proInfos.ForEach(p =>
{
if (proNames.Contains(p.Name))
{
dicPros.Add(p.Name, p);
}
});
foreach (string proName in proNames)
{
if (dicPros.ContainsKey(proName))
{
PropertyInfo proInfo = dicPros[proName];
object newValue = proInfo.GetValue(model, null);
foreach (T m in listModifes)
{
proInfo.SetValue(m, newValue, null);
}
}
}
return db.SaveChanges();
} /// <summary>
/// 批量修改(支持lambda)
/// </summary>
/// <param name="model">要修改实体中 修改后的属性 </param>
/// <param name="whereLambda">查询实体的条件</param>
/// <param name="proNames">lambda的形式表示要修改的实体属性名</param>
/// <returns></returns>
public int ModifyBy(T model, Expression<Func<T, bool>> whereLambda, params Expression<Func<T, object>>[] proNames)
{
List<T> listModifes = db.Set<T>().Where(whereLambda).ToList();
Type t = typeof(T);
List<PropertyInfo> proInfos = t.GetProperties(BindingFlags.Instance | BindingFlags.Public).ToList();
Dictionary<string, PropertyInfo> dicPros = new Dictionary<string, PropertyInfo>();
if (proNames != null)
{
foreach (var myProperyExp in proNames)
{
var my_ProName = new PropertyExpressionParser<T>(myProperyExp).Name;
proInfos.ForEach(p =>
{
if (p.Name.Equals(my_ProName))
{
dicPros.Add(p.Name, p);
}
});
if (dicPros.ContainsKey(my_ProName))
{
PropertyInfo proInfo = dicPros[my_ProName];
object newValue = proInfo.GetValue(model, null);
foreach (T m in listModifes)
{
proInfo.SetValue(m, newValue, null);
}
}
}
}
return db.SaveChanges();
}

3. EF增删改封装(事务分离)

 (1). 事务批量处理

         /// <summary>
/// 事务批量处理
/// </summary>
/// <returns></returns>
public int SaveChange()
{
return db.SaveChanges();
}

(2). 新增

         /// <summary>
/// 新增
/// </summary>
/// <param name="model">需要新增的实体</param>
public void AddNo(T model)
{
db.Set<T>().Add(model);
}

(3). 修改

         /// <summary>
/// 修改
/// </summary>
/// <param name="model">修改后的实体</param>
public void ModifyNo(T model)
{
db.Entry(model).State = EntityState.Modified;
}

(4). 删除

        /// <summary>
/// 删除
/// </summary>
/// <param name="model">需要删除的实体</param>
public void DelNo(T model)
{
db.Entry(model).State = EntityState.Deleted;
}
/// <summary>
/// 条件删除
/// </summary>
/// <param name="delWhere">需要删除的条件</param>
public void DelByNo(Expression<Func<T, bool>> delWhere)
{
List<T> listDels = db.Set<T>().Where(delWhere).ToList();
listDels.ForEach(d =>
{
db.Set<T>().Attach(d);
db.Set<T>().Remove(d);
});
}

4. Z.EntityFramework.Extensions 插件封装

方案一:在使用EF事务分离的方法的前提下,单独调用提交方法

         /// <summary>
/// 事务提交,速度约为saveChange的10倍-15倍
/// </summary>
public void BulkSaveChanges()
{
db.BulkSaveChanges();
}

方案二:插件特有的增删改方法

        /// <summary>
/// 新增
/// </summary>
/// <param name="model">新增的实体集合</param>
public void BulkInsert(List<T> model)
{
db.BulkInsert<T>(model);
}
/// <summary>
/// 删除
/// </summary>
/// <param name="model">需要删除的实体集合</param>
public void BulkDelete(List<T> model)
{
db.BulkDelete<T>(model);
}
/// <summary>
/// 根据条件删除
/// </summary>
/// <param name="delWhere">删除条件</param>
public void BulkDeleteBy(Expression<Func<T, bool>> delWhere)
{
List<T> listDels = db.Set<T>().Where(delWhere).ToList();
db.BulkDelete<T>(listDels);
}
/// <summary>
/// 需要修改的实体集合
/// </summary>
/// <param name="model"></param>
public void BulkUpdate(List<T> model)
{
db.BulkUpdate<T>(model);
}

  未完,后续会不断更新。

第十九节: 结合【表达式目录树】来封装EF的BaseDal层的方法的更多相关文章

  1. 表达式目录树(Expression)

    一:什么是表达式树 Expression我们称为是表达式树,是一种数据结构体,用于存储需要计算,运算的一种结构,这种结构可以只是存储,而不进行运算.通常表达式目录树是配合Lambda一起来使用的,la ...

  2. 05.表达式目录树Expression

    参考文章 https://www.cnblogs.com/xyh9039/p/12748983.html 1. 基本了解 1.1 Lambda表达式 演变过程 using System; namesp ...

  3. 第十五节:Expression表达式目录树(与委托的区别、自行拼接、总结几类实例间的拷贝)

    一. 基本介绍 回忆: 最早接触到表达式目录树(Expression)可能要追溯到几年前使用EF早期的时候,发现where方法里的参数是Expression<Func<T,bool> ...

  4. 第三百三十九节,Python分布式爬虫打造搜索引擎Scrapy精讲—Scrapy启动文件的配置—xpath表达式

    第三百三十九节,Python分布式爬虫打造搜索引擎Scrapy精讲—Scrapy启动文件的配置—xpath表达式 我们自定义一个main.py来作为启动文件 main.py #!/usr/bin/en ...

  5. 大白话5分钟带你走进人工智能-第二十九节集成学习之随机森林随机方式 ,out of bag data及代码(2)

              大白话5分钟带你走进人工智能-第二十九节集成学习之随机森林随机方式 ,out  of  bag  data及代码(2) 上一节中我们讲解了随机森林的基本概念,本节的话我们讲解随机森 ...

  6. 第三百七十九节,Django+Xadmin打造上线标准的在线教育平台—xadmin的安装

    第三百七十九节,Django+Xadmin打造上线标准的在线教育平台—xadmin的安装 xadmin介绍 xadmin是基于Django的admin开发的更完善的后台管理系统,页面基于Bootstr ...

  7. 第三百五十九节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)介绍以及安装

    第三百五十九节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)介绍以及安装 elasticsearch(搜索引擎)介绍 ElasticSearch是一个基于 ...

  8. centos MySQL主从配置 ntsysv chkconfig setup命令 配置MySQL 主从 子shell MySQL备份 kill命令 pid文件 discuz!论坛数据库读写分离 双主搭建 mysql.history 第二十九节课

    centos  MySQL主从配置 ntsysv   chkconfig  setup命令  配置MySQL 主从 子shell  MySQL备份  kill命令  pid文件  discuz!论坛数 ...

  9. centos LAMP第一部分-环境搭建 Linux软件删除方式,mysql安装,apache,PHP,apache和php结合,phpinfo页面,ldd命令 第十九节课

    centos LAMP第一部分-环境搭建  Linux软件删除方式,mysql安装,apache,PHP,apache和php结合,phpinfo页面,ldd命令 第十九节课 打命令之后可以输入: e ...

随机推荐

  1. [经验总结] 从其它sheet页引用数据生成图表时没有图例的解决办法

    1.先给出一个在有数据区域的sheet页中生成的图表,比较全,图表和图例全部都有,如下图: 2.但是如果在其它 sheet页中引用该有数据的sheet数据时并生成图表,生成的图表只有图表区域显示,图例 ...

  2. 【English】20190313

     indicators指针['ɪndɪkeɪtəz]  determine决定[dɪˈtɜ:rmɪn] Places null indicator bits at the front of each ...

  3. Django 【认证系统】auth

    本篇内容 介绍Django框架提供的auth 认证系统 方法: 方法名 备注 create_user 创建用户 authenticate 登录验证 login 记录登录状态 logout 退出用户登录 ...

  4. Spring Security(三十四):10.4 Jackson Support

    Spring Security has added Jackson Support for persisting Spring Security related classes. This can i ...

  5. C# 将普通字符串转换为二进制字符串

    1.因为项目的需要,在向数据库中添加人的信息时,必须要求是英文或数字,所以想了个办法,将我们人能看懂的字符串编译成二进制字符串转入就行了. 具体的逻辑实现代码如下:

  6. Linux内存管理 (22)内存检测技术(slub_debug/kmemleak/kasan)

    专题:Linux内存管理专题 关键词:slub_debug.kmemleak.kasan.oob.Redzone.Padding. Linux常见的内存访问错误有: 越界访问(out of bound ...

  7. Entity Framework Core系列之DbContext(删除)

    上一篇我们介绍了Entity Framework Core系列之DbContext(修改),这一篇我们介绍下删除数据 修改实体的方法取决于context是否正在跟踪需要删除的实体. 下面的示例中con ...

  8. [硬件]超能课堂(181):我们为什么需要4+8pin CPU供电接口?

    超能课堂(181):我们为什么需要4+8pin CPU供电接口? https://www.expreview.com/68008.html 之前算过TDP 来计算机器的功耗 发现自己 理解的还是有偏差 ...

  9. [转帖]SAP S4 HANA 1610与ECC的比较

    SAP S4 HANA 1610与ECC的比较 https://zhuanlan.zhihu.com/p/27266476 SAP S4 HANA是下一代的ERP套件,是SAP 战略的核心,相关资料也 ...

  10. 搭建Android手机服务器(一)

    自从上学期的软件工程课之后,我们团队设计的抢答器一直想把服务端移到移动端.所以,我一直在考虑如何把手机作为一台服务器.今天我主要讲解一下,对于没有android真机只有模拟器的,如何设置模拟器,使得在 ...