第十九节: 结合【表达式目录树】来封装EF的BaseDal层的方法
一. 简介
该章节,可以说是一个简单轻松的章节,只要你对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层的方法的更多相关文章
- 表达式目录树(Expression)
一:什么是表达式树 Expression我们称为是表达式树,是一种数据结构体,用于存储需要计算,运算的一种结构,这种结构可以只是存储,而不进行运算.通常表达式目录树是配合Lambda一起来使用的,la ...
- 05.表达式目录树Expression
参考文章 https://www.cnblogs.com/xyh9039/p/12748983.html 1. 基本了解 1.1 Lambda表达式 演变过程 using System; namesp ...
- 第十五节:Expression表达式目录树(与委托的区别、自行拼接、总结几类实例间的拷贝)
一. 基本介绍 回忆: 最早接触到表达式目录树(Expression)可能要追溯到几年前使用EF早期的时候,发现where方法里的参数是Expression<Func<T,bool> ...
- 第三百三十九节,Python分布式爬虫打造搜索引擎Scrapy精讲—Scrapy启动文件的配置—xpath表达式
第三百三十九节,Python分布式爬虫打造搜索引擎Scrapy精讲—Scrapy启动文件的配置—xpath表达式 我们自定义一个main.py来作为启动文件 main.py #!/usr/bin/en ...
- 大白话5分钟带你走进人工智能-第二十九节集成学习之随机森林随机方式 ,out of bag data及代码(2)
大白话5分钟带你走进人工智能-第二十九节集成学习之随机森林随机方式 ,out of bag data及代码(2) 上一节中我们讲解了随机森林的基本概念,本节的话我们讲解随机森 ...
- 第三百七十九节,Django+Xadmin打造上线标准的在线教育平台—xadmin的安装
第三百七十九节,Django+Xadmin打造上线标准的在线教育平台—xadmin的安装 xadmin介绍 xadmin是基于Django的admin开发的更完善的后台管理系统,页面基于Bootstr ...
- 第三百五十九节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)介绍以及安装
第三百五十九节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)介绍以及安装 elasticsearch(搜索引擎)介绍 ElasticSearch是一个基于 ...
- centos MySQL主从配置 ntsysv chkconfig setup命令 配置MySQL 主从 子shell MySQL备份 kill命令 pid文件 discuz!论坛数据库读写分离 双主搭建 mysql.history 第二十九节课
centos MySQL主从配置 ntsysv chkconfig setup命令 配置MySQL 主从 子shell MySQL备份 kill命令 pid文件 discuz!论坛数 ...
- centos LAMP第一部分-环境搭建 Linux软件删除方式,mysql安装,apache,PHP,apache和php结合,phpinfo页面,ldd命令 第十九节课
centos LAMP第一部分-环境搭建 Linux软件删除方式,mysql安装,apache,PHP,apache和php结合,phpinfo页面,ldd命令 第十九节课 打命令之后可以输入: e ...
随机推荐
- Saltstack_使用指南06_远程执行-指定目标
1. 主机规划 Targeting Minions文档 https://docs.saltstack.com/en/latest/contents.html 另请参见:自动化运维神器之saltstac ...
- webstorm 的 .后缀名-tab快捷键
if (key) {}//key.if tab if (!key) {}//key.else tab if (key != null) {}//key.notnull tab if (typeof k ...
- jvisualvm 连接 jstatd 远程监控 jvm 或 Visual GC提示"不受此JVM支持“
Visual GC提示"不受此JVM支持",可以使用此方法解决. 一.添加配置文件 jstatd.all.policy [root@localhost /]# cd /usr/lo ...
- Log4j分级别存储日志到数据库
首先先创建三张表,按照自己的需求创建 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE lo ...
- docker 常用命令和常用容器启动
docker:systemctl start docker # docker 启动systemctl stop docker # docker 停止systemctl restart docker # ...
- 理解OSI参考模型(转)
文章转自 https://www.cnblogs.com/evablogs/p/6709707.html 一个视频网站上不小心搜到网络知识的视频,突然以前大学的没有真正接受的知识点,一下子豁然开朗,赶 ...
- 【接口时序】6、IIC总线的原理与Verilog实现
一. 软件平台与硬件平台 软件平台: 1.操作系统:Windows-8.1 2.开发套件:ISE14.7 3.仿真工具:ModelSim-10.4-SE .ChipScope 硬件平台: 1. FPG ...
- linux java 和jmeter 环境变量配置文件笔记(原)
我在EC2 亚马逊的ubuntu系统下进行的配置,步骤如下(非常简单) 1.在/usr/local下分别新建java和jmeter文件夹,把下载的包进行解压 注:此处有坑,需注意ll -lht 查看 ...
- SyntaxError: missing ) after argument list
消息 语法错误: 参数列表后面缺少 ) 错误类型 SyntaxError. 什么地方出错了? 有一个函数在调用时出现错误.这可能是一个错误,丢失运算符或者转义字符等. 示例 因为没有使用 ”+“ 操作 ...
- spring4配置文件详解
转自: spring4配置文件详解 一.配置数据源 基本的加载properties配置文件 <context:property-placeholder location="classp ...