本篇是对EFCore 进行下封装并实现基本的增删改查的同步异步方法及针对不同数据库的批量插入、sql语句直接操作数据库;

一、 先定义基础仓储接口IRepository

  public  interface IRepository<TEntity,TKey> where TEntity : class
{
#region 查找数据
long Count(Expression<Func<TEntity, bool>> predicate = null);
Task<long> CountAsync(Expression<Func<TEntity, bool>> predicate = null); TEntity Get(Expression<Func<TEntity, bool>> predicate, bool isNoTracking);
Task<TEntity> GetAsync(Expression<Func<TEntity, bool>> predicate, bool isNoTracking); Task<TEntity> GetAsync(TKey id); IQueryable<TEntity> Load(Expression<Func<TEntity, bool>> predicate , bool isNoTracking);
Task<IQueryable<TEntity>> LoadAsync(Expression<Func<TEntity, bool>> predicate , bool isNoTracking); List<TEntity> GetList(Expression<Func<TEntity, bool>> predicate, string ordering, bool isNoTracking );
Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> predicate, string ordering, bool isNoTracking ); #endregion #region 插入数据
bool Insert(TEntity entity, bool isSaveChange);
Task<bool> InsertAsync(TEntity entity, bool isSaveChange);
bool Insert(List<TEntity> entitys, bool isSaveChange = true);
Task<bool> InsertAsync(List<TEntity> entitys, bool isSaveChange);
#endregion #region 删除(删除之前需要查询)
bool Delete(TEntity entity, bool isSaveChange);
bool Delete(List<TEntity> entitys, bool isSaveChange);
Task<bool> DeleteAsync(TEntity entity, bool isSaveChange);
Task<bool> DeleteAsync(List<TEntity> entitys, bool isSaveChange = true);
#endregion #region 修改数据
bool Update(TEntity entity, bool isSaveChange, List<string> updatePropertyList);
Task<bool> UpdateAsync(TEntity entity, bool isSaveChange, List<string> updatePropertyList);
bool Update(List<TEntity> entitys, bool isSaveChange);
Task<bool> UpdateAsync(List<TEntity> entitys, bool isSaveChange );
#endregion #region 执行Sql语句
void BulkInsert<T>(List<T> entities);
int ExecuteSql(string sql);
Task<int> ExecuteSqlAsync(string sql);
int ExecuteSql(string sql, List<DbParameter> spList);
Task<int> ExecuteSqlAsync(string sql, List<DbParameter> spList);
DataTable GetDataTableWithSql(string sql); DataTable GetDataTableWithSql(string sql, List<DbParameter> spList); #endregion

二、实现IRepository接口

   public abstract  class BaseRepository<TEntity,TKey> :IRepository<TEntity,TKey> where TEntity : class
{
private readonly DbSet<TEntity> _dbSet;
public GeneralDbContext _dbContext { get; } = null; /// <summary>
/// 连接字符串
/// </summary>
protected string _connectionString { get; set; } /// <summary>
/// 数据库类型
/// </summary>
private DatabaseType _dbType { get; set; }
public BaseRepository(GeneralDbContext context)
{
_dbContext = context;
_dbSet = _dbContext.Set<TEntity>();
}
public DatabaseFacade Database => _dbContext.Database;
public IQueryable<TEntity> Entities => _dbSet.AsQueryable().AsNoTracking();
public int SaveChanges()
{
return _dbContext.SaveChanges();
}
public async Task<int> SaveChangesAsync()
{
return await _dbContext.SaveChangesAsync();
}
public bool Any(Expression<Func<TEntity, bool>> whereLambd)
{
return _dbSet.Where(whereLambd).Any();
}
#region 插入数据
public bool Insert(TEntity entity, bool isSaveChange = true)
{
_dbSet.Add(entity);
if (isSaveChange)
{
return SaveChanges() > ;
}
return false;
}
public async Task<bool> InsertAsync(TEntity entity, bool isSaveChange = true)
{
_dbSet.Add(entity);
if (isSaveChange)
{
return await SaveChangesAsync() > ;
}
return false;
}
public bool Insert(List<TEntity> entitys, bool isSaveChange = true)
{
_dbSet.AddRange(entitys);
if (isSaveChange)
{
return SaveChanges() > ;
}
return false;
}
public async Task<bool> InsertAsync(List<TEntity> entitys, bool isSaveChange = true)
{
_dbSet.AddRange(entitys);
if (isSaveChange)
{
return await SaveChangesAsync() > ;
}
return false;
}
#endregion #region 删除
public bool Delete(TEntity entity, bool isSaveChange = true)
{
_dbSet.Attach(entity);
_dbSet.Remove(entity);
return isSaveChange ? SaveChanges() > : false;
}
public bool Delete(List<TEntity> entitys, bool isSaveChange = true)
{
entitys.ForEach(entity =>
{
_dbSet.Attach(entity);
_dbSet.Remove(entity);
});
return isSaveChange ? SaveChanges() > : false;
} public virtual async Task<bool> DeleteAsync(TEntity entity, bool isSaveChange = true)
{ _dbSet.Attach(entity);
_dbSet.Remove(entity);
return isSaveChange ? await SaveChangesAsync() > : false;
}
public virtual async Task<bool> DeleteAsync(List<TEntity> entitys, bool isSaveChange = true)
{
entitys.ForEach(entity =>
{
_dbSet.Attach(entity);
_dbSet.Remove(entity);
});
return isSaveChange ? await SaveChangesAsync() > : false;
}
#endregion #region 更新数据
public bool Update(TEntity entity, bool isSaveChange = true, List<string> updatePropertyList = null)
{
if (entity == null)
{
return false;
}
_dbSet.Attach(entity);
var entry = _dbContext.Entry(entity);
if (updatePropertyList == null)
{
entry.State = EntityState.Modified;//全字段更新
}
else
{ updatePropertyList.ForEach(c => {
entry.Property(c).IsModified = true; //部分字段更新的写法
}); }
if (isSaveChange)
{
return SaveChanges() > ;
}
return false;
}
public bool Update(List<TEntity> entitys, bool isSaveChange = true)
{
if (entitys == null || entitys.Count == )
{
return false;
}
entitys.ForEach(c => {
Update(c, false);
});
if (isSaveChange)
{
return SaveChanges() > ;
}
return false;
}
public async Task<bool> UpdateAsync(TEntity entity, bool isSaveChange = true, List<string> updatePropertyList = null)
{
if (entity == null)
{
return false;
}
_dbSet.Attach(entity);
var entry = _dbContext.Entry<TEntity>(entity);
if (updatePropertyList == null)
{
entry.State = EntityState.Modified;//全字段更新
}
else
{
updatePropertyList.ForEach(c => {
entry.Property(c).IsModified = true; //部分字段更新的写法
}); }
if (isSaveChange)
{
return await SaveChangesAsync() > ;
}
return false;
}
public async Task<bool> UpdateAsync(List<TEntity> entitys, bool isSaveChange = true)
{
if (entitys == null || entitys.Count == )
{
return false;
}
entitys.ForEach(c => {
_dbSet.Attach(c);
_dbContext.Entry<TEntity>(c).State = EntityState.Modified;
});
if (isSaveChange)
{
return await SaveChangesAsync() > ;
}
return false;
} #endregion #region 查找
public long Count(Expression<Func<TEntity, bool>> predicate = null)
{
if (predicate == null)
{
predicate = c => true;
}
return _dbSet.LongCount(predicate);
}
public async Task<long> CountAsync(Expression<Func<TEntity, bool>> predicate = null)
{
if (predicate == null)
{
predicate = c => true;
}
return await _dbSet.LongCountAsync(predicate);
}
public TEntity Get(TKey id)
{
if (id == null)
{
return default(TEntity);
}
return _dbSet.Find(id);
} public TEntity Get(Expression<Func<TEntity, bool>> predicate = null, bool isNoTracking = true)
{
var data = isNoTracking ? _dbSet.Where(predicate).AsNoTracking() : _dbSet.Where(predicate);
return data.FirstOrDefault();
} public async Task<TEntity> GetAsync(TKey id)
{
if (id == null)
{
return default(TEntity);
}
return await _dbSet.FindAsync(id);
}
public async Task<TEntity> GetAsync(Expression<Func<TEntity, bool>> predicate = null, bool isNoTracking = true)
{
var data = isNoTracking ? _dbSet.Where(predicate).AsNoTracking() : _dbSet.Where(predicate);
return await data.FirstOrDefaultAsync();
} public async Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> predicate = null, string ordering = "", bool isNoTracking = true)
{
var data = isNoTracking ? _dbSet.Where(predicate).AsNoTracking() : _dbSet.Where(predicate);
if (!string.IsNullOrEmpty(ordering))
{
data = data.OrderByBatch(ordering);
}
return await data.ToListAsync();
}
public List<TEntity> GetList(Expression<Func<TEntity, bool>> predicate = null, string ordering = "", bool isNoTracking = true)
{
var data = isNoTracking ? _dbSet.Where(predicate).AsNoTracking() : _dbSet.Where(predicate);
if (!string.IsNullOrEmpty(ordering))
{
data = data.OrderByBatch(ordering);
}
return data.ToList();
}
public async Task<IQueryable<TEntity>> LoadAsync(Expression<Func<TEntity, bool>> predicate = null, bool isNoTracking = true)
{
if (predicate == null)
{
predicate = c => true;
}
return await Task.Run(() => isNoTracking ? _dbSet.Where(predicate).AsNoTracking() : _dbSet.Where(predicate));
}
public IQueryable<TEntity> Load(Expression<Func<TEntity, bool>> predicate = null, bool isNoTracking = true)
{
if (predicate == null)
{
predicate = c => true;
}
return isNoTracking ? _dbSet.Where(predicate).AsNoTracking() : _dbSet.Where(predicate);
} #endregion #region SQL语句
public virtual void BulkInsert<T>(List<T> entities)
{ }
public int ExecuteSql(string sql)
{
return _dbContext.Database.ExecuteSqlCommand(sql) ;
} public Task<int> ExecuteSqlAsync(string sql)
{
return _dbContext.Database.ExecuteSqlCommandAsync(sql);
} public int ExecuteSql(string sql, List<DbParameter> spList)
{
return _dbContext.Database.ExecuteSqlCommand(sql, spList.ToArray());
} public Task<int> ExecuteSqlAsync(string sql, List<DbParameter> spList)
{
return _dbContext.Database.ExecuteSqlCommandAsync(sql, spList.ToArray());
} public virtual DataTable GetDataTableWithSql(string sql)
{
throw new NotImplementedException();
} public virtual DataTable GetDataTableWithSql(string sql, List<DbParameter> spList)
{
throw new NotImplementedException();
} #endregion

三、BaseRepository是个抽象类,有些比较复杂的sql语句通过EF来处理比较麻烦,还需要直接操作sql语句的方法,因不同的数据库sql语句不一样,针对不同的数据,继承BaseRepository这个基类,重写sql语句方法,下面简单实现SqlServerRepository仓储

 public   class SqlServerRepository<TEntity,TKey>: BaseRepository<TEntity,TKey>,IRepository<TEntity,TKey> where TEntity : class
{
protected ConfigOption _dbOpion;
public SqlServerRepository(GeneralDbContext generalDbContext,IOptionsSnapshot<ConfigOption> options)
:base(generalDbContext)
{
_dbOpion = options.Get("config");
_connectionString = _dbOpion.ReadWriteHosts;
} #region 插入数据 /// <summary>
/// 使用Bulk批量插入数据(适合大数据量,速度非常快)
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
/// <param name="entities">数据</param>
public override void BulkInsert<T>(List<T> entities)
{
using (SqlConnection conn = new SqlConnection())
{
conn.ConnectionString =_connectionString ;
if (conn.State != ConnectionState.Open)
{
conn.Open();
} string tableName = string.Empty;
var tableAttribute = typeof(T).GetCustomAttributes(typeof(TableAttribute), true).FirstOrDefault();
if (tableAttribute != null)
tableName = ((TableAttribute)tableAttribute).Name;
else
tableName = typeof(T).Name; SqlBulkCopy sqlBC = new SqlBulkCopy(conn)
{
BatchSize = ,
BulkCopyTimeout = ,
DestinationTableName = tableName
};
using (sqlBC)
{
sqlBC.WriteToServer(entities.ToDataTable());
}
}
} public override DataTable GetDataTableWithSql(string sql)
{
return GetDataTableWithSql(sql);
} public override DataTable GetDataTableWithSql(string sql, List<DbParameter> spList=null)
{
DataTable dt = new DataTable(); ;
using (SqlConnection conn = new SqlConnection(_connectionString))
{
SqlDataAdapter da = new SqlDataAdapter(sql, conn);
da.SelectCommand.CommandType = CommandType.Text;
if (spList.ToArray() != null)
{
da.SelectCommand.Parameters.AddRange(spList.ToArray());
}
da.Fill(dt);
}
return dt;
}
#endregion
}

引用了http://www.cnblogs.com/coldairarrow/p/9626691.html该框架设计思想及部分代码

利用EFCore 封装Repository(可扩展不同数据的sql操作)的更多相关文章

  1. ICMP 隧道——将流量封装进 IMCP 的 ping 数据包中,旨在利用 ping 穿透防火墙的检测

    利用 ICMP 隧道穿透防火墙 转自:http://xiaix.me/li-yong-icmp-sui-dao-chuan-tou-fang-huo-qiang/ 以前穿透防火墙总是使用 SSH 隧道 ...

  2. Util应用程序框架公共操作类(三):数据类型转换公共操作类(扩展篇)

    上一篇以TDD方式介绍了数据类型转换公共操作类的开发,并提供了单元测试和实现代码,本文将演示通过扩展方法来增强公共操作类,以便调用时更加简化. 下面以字符串转换为List<Guid>为例进 ...

  3. 利用window.name+iframe跨域获取数据详解

    详解 前文提到用jsonp的方式来跨域获取数据,本文为大家介绍下如何利用window.name+iframe跨域获取数据. 首先我们要简单了解下window.name和iframe的相关知识.ifra ...

  4. 导入导出封装的工具类 (一) 利用POI封装

    对于导入导出各个项目中差点儿都会用到,记得在高校平台中封装过导入导出这部分今天看了看是利用JXL封装的而经理说让我用POI写写导出,这两个导入导出框架是眼下比較流程和经常使用的框架,有必要都了解一下. ...

  5. iframe 跨域问题解决方案 利用window.name+iframe跨域获取数据详解

    详解 前文提到用jsonp的方式来跨域获取数据,本文为大家介绍下如何利用window.name+iframe跨域获取数据. 首先我们要简单了解下window.name和iframe的相关知识.ifra ...

  6. block传值以及利用block封装一个网络请求类

    1.block在俩个UIViewController间传值 近期刚学了几招block 的高级使用方法,事实上就是利用block语法在俩个UIViewController之间传值,在这里分享给刚開始学习 ...

  7. 利用XtraBackup给MYSQL热备(基于数据文件)

    利用XtraBackup给MYSQL热备(基于数据文件) By JRoBot on 2013 年 11 月 26 日 | Leave a response 利用XtraBackup给MYSQL热备(基 ...

  8. 利用ant-design封装react的地址输入组件

    在上一节利用element-ui封装地址输入的组件留下了个尾巴,说react搭配ant-design封装一下地址输入的组件的.本来应该早早就完成的,但是由于这中间发生了一些事情,导致了突发性的换了工作 ...

  9. 利用Jackson封装常用JsonUtil工具类

    在日常的项目开发中,接口与接口之间.前后端之间的数据传输一般都是使用JSON格式,那必然会封装一些常用的Json数据转化的工具类,本文讲解下如何利用Jackson封装高复用性的Json转换工具类. 转 ...

随机推荐

  1. 第01章 开发准备(对最新版的RN进行了升级)1-2+项目技术分解

  2. codeforce 457DIV2 C题

    题意 你需要构造一个n个点m条边的无向有权图,要求这个图的MST中边权的和与从1到n的最短路长度都为素数 分析 可以想到这样一种贪心,在i到i+1直接连一条边,这样最短路和MST都会是同样的一些边.只 ...

  3. 447. Number of Boomerangs 回力镖数组的数量

    [抄题]: Given n points in the plane that are all pairwise distinct, a "boomerang" is a tuple ...

  4. oracle 创建表 外键约束

    create table usertable( id int primary key, username ) not null, birthday date, sex ), address ) ); ...

  5. 安装 SQL Server 2014 Express

    安装 SQL Server 2014 Express 我的电脑系统: Windows 10 64位 一 . 下载 安装Microsoft SQL Server 2014 Express 软甲下载地址: ...

  6. Docker学习之路(三)Docker网络详解

    1. Docker的4种网络模式 我们在使用docker run创建Docker容器时,可以用--net选项指定容器的网络模式,Docker有以下4种网络模式: host模式,使用--net=host ...

  7. eWebEditor9.x整合教程-Xproer.WordPaster

    版权所有 2009-2017 荆门泽优软件有限公司 保留所有权利 官方网站:http://www.ncmem.com/ 产品首页:http://www.ncmem.com/webplug/wordpa ...

  8. (转)第一次发博客-说说我的B/S开发框架(asp.net mvc + web api + easyui)

    原文地址:http://www.cnblogs.com/xqin/archive/2013/05/29/3105291.html 前言 这些年一直在.net下做企业web系统开发,前前后后经历的不同的 ...

  9. word 2013如何从某一页开始插入页码

    把光标移入要插入页面的最前面 插入分页符 在要插入页码的页脚双击打开页脚设计 取消页脚和前面页眉的链接 插入页码

  10. Js杂谈-单体模式

    单体模式的思想:保证一个特定类仅有一个实例,意味着第二次使用同一个类创建新对象的时候,应该得到与第一次所创建对象完全相同的对象. 下面举几个实现的例子 1.new操作符 这种思想在于当使用同一个构造函 ...