本篇是对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. layer使用总结一配置

    导入layer.js文件即可,必须先导入jquery.js文件,因为layer是基于jquery 版本匹配,在此记录一下,layer使用1.8下载时是2.3的版本,对应的jquery使用1.8.3版本 ...

  2. 10.LIKE 操作符

    LIKE 操作符用于在 WHERE 子句中搜索列中的指定模式. LIKE 操作符 LIKE 操作符用于在 WHERE 子句中搜索列中的指定模式. SQL LIKE 操作符语法 SELECT colum ...

  3. laravel实现多对多的分析

    在实际开发中多对多的开发还是比较常见的 1.1首先由migrate来创建表(文章表) 1.2同理创建标签表 1.3这是 我会的到如下结果: 2.1在数据迁移表contents中添加几个字段 publi ...

  4. ef增删改查

    [C#]Entity Framework 增删改查和事务操作 1.增加对象 DbEntity db = new DbEntity(); //创建对象实体,注意,这里需要对所有属性进行赋值(除了自动增长 ...

  5. Schwartz kernel theorem施瓦兹核定理

    In mathematics, the Schwartz kernel theorem is a foundational result in the theory of generalized fu ...

  6. 献上一款漂亮的手写PHP验证码

    献上一款漂亮的PHP验证码,可以根据个人需求作调整,代码如下(审美观不同,欢迎吐槽): <?php /** * Author: xiongwei * Email: 695704253@qq.co ...

  7. SQL聚集索引和非聚集索引的区别

    其实对于非专业的数据库操作人员来讲,例如软件开发人员,在很大程度上都搞不清楚数据库索引的一些基本知识,有些是知其一不知其二,或者是知其然不知其所以然.造成这种情况的主要原因我觉的是行业原因,有很多公司 ...

  8. 图的遍历——BFS

    原创 裸一篇图的BFS遍历,直接来图: 简单介绍一下BFS遍历的过程: 以上图为例子,从0开始遍历,访问0,按大小顺序访问与0相邻的所有顶点,即先访问1,再访问2: 至此顶点0已经没有作用了,因为其本 ...

  9. DELPHI XE5 跨平台 Form ShowModal 官方示例

    Calling ShowModal as an Anonymous Method on All Platforms procedure THeaderFooterForm.btnPickClick(S ...

  10. xp 专业版组策略只有系统组件

    想要不显示任务栏的提示消息,需要在组策略里面设置,(在"开始→运行"中输入"GPEDIT.MSC"打开组策略,然后依次选择"用户配置→管理模板→任务栏 ...