一. 简介

  该章节,可以说是一个简单轻松的章节,只要你对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. A Deep Learning-Based System for Vulnerability Detection(一)

    接着上一篇,讨论讨论具体步骤实现方法.步骤1-3分别在下面进行阐述,步骤4,6都是标准的,步骤5类似于步骤1-3. 结合这个图进行讨论详细步骤: 步骤1:提取库/API函数调用和程序片段 1.1将库/ ...

  2. spark-2.4.0-hadoop2.7-安装部署

    1. 主机规划 主机名称 IP地址 操作系统 部署软件 运行进程 备注 mini01 172.16.1.11[内网] 10.0.0.11  [外网] CentOS 7.5 Jdk-8.zookeepe ...

  3. Windows Server 2012 R2 配置FTP服务器

    Windows Server 2012 R2 安装IIS参考上一篇配置IIS 8.0:https://www.cnblogs.com/aq-ry/p/9329310.html 搭建完IIS 后,最近又 ...

  4. LeetCode算法题-Island Perimeter(Java实现)

    这是悦乐书的第238次更新,第251篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第105题(顺位题号是463).您将获得一个二维整数网格形式的地图,其中1代表土地,0代 ...

  5. 5.机器学习——DBSCAN聚类算法

    1.优缺点 优点: (1)聚类速度快且能够有效处理噪声点和发现任意形状的空间聚类: (2)与K-MEANS比较起来,不需要输入要划分的聚类个数: (3)聚类簇的形状没有偏倚: (4)可以在需要时输入过 ...

  6. 《PHP扩展及核心》

    本文地址:http://www.cnblogs.com/aiweixiao/p/8202365.html 原文地址: 欢迎关注微信公众号  程序员的文娱情怀 一.主要内容: 1️⃣php扩展的概念和底 ...

  7. 【Linux基础】mount报错:mount.nfs: Remote I/O error

    问题描述:mount 报错:mount.nfs: Remote I/O error 挂载时需要指明版本,由于NFS服务器有多个版本,V2.V3.V4.而且各版本同时运行,因此挂载时需要说明版本号. 由 ...

  8. HBase源码实战:BufferedMutator

    /** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agr ...

  9. slice()和splice()区别

    1.slice(start,end):方法可从已有数组中返回选定的元素,返回一个新数组,包含从start到end(不包含该元素)的数组元素. 注意:该方法不会改变原数组,而是返回一个子数组,如果想删除 ...

  10. SpringBoot学习笔记(2) Spring Boot的一些配置

    外部配置 Spring Boot允许使用properties文件.yaml文件或者命令行参数作为外部配置 使用@Value注解,可以直接将属性值注入到你的beans中,并通过Spring的Enviro ...