第十九节: 结合【表达式目录树】来封装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 ...
随机推荐
- 重装助手教你如何在Windows 10中更改您的帐户名称
当您设置新的Win10免费下载 PC时,您选择用户名的部分可能会让您措手不及.如果是这种情况,您可以选择弹出头部的第一件事或者您打算稍后更改的随机和临时事物.但令人惊讶的是,在Windows 10中更 ...
- Python 位操作运算符
& 按位与运算符:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0 (a & b) 输出结果 12 ,二进制解释: 0000 1100 | 按位或运算符:只要对应的二 ...
- javascript基础之函数
javascript的函数定义与python有很大的区别,的记住格式就好,下面请看代码 // 函数 // 简单定义 function func() { console.log('hello word' ...
- ASP.NET基础知识汇总之WebConfig各节点介绍
web.config虽然一直用,接触最多的也就是节点appSettings和connectionSettings,今天系统的梳理一下,了解一下webconfig各个节点的含义,先简单的浏览一下具体的w ...
- .NET CORE学习笔记系列(2)——依赖注入[5]: 创建一个简易版的DI框架[下篇]
为了让读者朋友们能够对.NET Core DI框架的实现原理具有一个深刻而认识,我们采用与之类似的设计构架了一个名为Cat的DI框架.在上篇中我们介绍了Cat的基本编程模式,接下来我们就来聊聊Cat的 ...
- mmap:速度快+整块操作
mmap使得可以将设备内存映射到用户空间,从而使得用户程序获得访问硬件的能力,mmap的动作需要由内核中的驱动来实现.在使用mmap映射后,用户程序对给定范围的内存的读写就变成了对设备内存的读写,也就 ...
- Spring Security(二十九):9.4.1 ExceptionTranslationFilter
ExceptionTranslationFilter is a Spring Security filter that has responsibility for detecting any Spr ...
- Auto Layout: Programmatic Constraints - BNR
继续Auto Layout - BNR篇. 打开BNRDetailViewController.m文件,重载viewDidLoad方法来创建UIImageView对象.当你想要给通过加载NIB文件创建 ...
- 从明面上学习ASP.NET Core
一.前言 这篇文章就是从能看到地方去学习Core,没有很深奥,也没有很难懂,现在我们开始吧. 二.构建项目,引发思考 创建项目的步骤真的很简单,你要是不会,我真也没法了,我这是创建的M ...
- (hdu)4858 项目管理 (vector)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4858 Problem Description 我们建造了一个大项目!这个项目有n个节点,用很多边连接起 ...