BaseDAL最牛数据层基类2
using System; using System.Data.Entity; using System.Linq; using System.Threading.Tasks; using System.Linq.Expressions; using YunEdu.Model; namespace DAL { /// <summary> /// EF数据库操作基类 /// </summary> /// <typeparam name="T"></typeparam> public partial class BaseDAL<T> where T : class, new() { /// <summary> /// 数据库上下文 /// </summary> private DbContext dbContext = DbContextFactory.Create(); /* * 2017-03-22 重新封装的方法 * 2017-03-26 更新方法添加异步 */ #region Add 添加实体 /// <summary> /// 添加 /// </summary> /// <param name="entity">实体</param> /// <param name="isSave">是否立即保存</param> /// <returns>添加的记录数[isSave=true时有效]</returns> public virtual int Add(T entity, bool isSave = true) { dbContext.Set<T>().Add(entity); if (isSave) return dbContext.SaveChanges(); else return 0; } /// <summary> /// 添加(异步) /// </summary> /// <param name="entity">实体</param> /// <param name="isSave">是否立即保存</param> /// <returns>添加的记录数[isSave=true时有效]</returns> public virtual async Task<int> AddAsync(T entity, bool isSave = true) { dbContext.Set<T>().Add(entity); if (isSave) return await dbContext.SaveChangesAsync(); else return 0; } /// <summary> /// 添加[批量] /// </summary> /// <param name="entities">实体</param> /// <param name="isSave">是否立即保存</param> /// <returns>添加的记录数[isSave=true时有效]</returns> public virtual int AddRange(T[] entities, bool isSave = true) { dbContext.Set<T>().AddRange(entities); if (isSave) return dbContext.SaveChanges(); else return 0; } /// <summary> /// 添加[批量](异步) /// </summary> /// <param name="entities">实体</param> /// <param name="isSave">是否立即保存</param> /// <returns>添加的记录数[isSave=true时有效]</returns> public virtual async Task<int> AddRangeAsync(T[] entities, bool isSave = true) { dbContext.Set<T>().AddRange(entities); if (isSave) return await dbContext.SaveChangesAsync(); else return 0; } #endregion #region Delete 删除实体 /// <summary> /// 删除 /// </summary> /// <param name="entity">实体</param> /// <param name="isSave">是否立即保存</param> /// <returns>是否删除成功[isSave=true时有效]</returns> public virtual bool Remove(T entity, bool isSave = true) { dbContext.Set<T>().Remove(entity); if (isSave) return dbContext.SaveChanges() > 0; else return false; } /// <summary> /// 删除(异步) /// </summary> /// <param name="entity">实体</param> /// <param name="isSave">是否立即保存</param> /// <returns>是否删除成功[isSave=true时有效]</returns> public virtual async Task<bool> RemoveAsync(T entity, bool isSave = true) { dbContext.Set<T>().Remove(entity); if (isSave) return await dbContext.SaveChangesAsync() > 0; else return false; } /// <summary> /// 批量删除 /// </summary> /// <param name="entities">实体数组</param> /// <param name="isSave">是否立即保存</param> /// <returns>成功删除的记录数</returns> public virtual int RemoveRange(T[] entities, bool isSave = true) { dbContext.Set<T>().RemoveRange(entities); if (isSave) return dbContext.SaveChanges(); else return 0; } /// <summary> /// 批量删除(异步) /// </summary> /// <param name="entities">实体数组</param> /// <param name="isSave">是否立即保存</param> /// <returns>成功删除的记录数[isSave=true时有效]</returns> public virtual async Task<int> RemoveRangeAsync(T[] entities, bool isSave = true) { dbContext.Set<T>().RemoveRange(entities); if (isSave) return await dbContext.SaveChangesAsync(); else return 0; } #endregion #region Update 更新实体 /// <summary> /// 更新实体 /// </summary> /// <param name="entity">实体</param> /// <param name="isSave">是否立即保存</param> /// <returns>在“isSave”为True时返回受影响的对象的数目,为False时直接返回0</returns> public virtual int Update(T entity, bool isSave) { dbContext.Set<T>().Attach(entity); dbContext.Entry<T>(entity).State = EntityState.Modified;//将所有属性标记为修改状态 return isSave ? dbContext.SaveChanges() : 0; } /// <summary> /// 更新实体(异步) /// </summary> /// <param name="entity">实体</param> /// <param name="isSave">是否立即保存</param> /// <returns>在“isSave”为True时返回受影响的对象的数目,为False时直接返回0</returns> public async virtual Task<int> UpdateAsync(T entity, bool isSave) { dbContext.Set<T>().Attach(entity); dbContext.Entry<T>(entity).State = EntityState.Modified;//将所有属性标记为修改状态 if (isSave) return await dbContext.SaveChangesAsync(); return 0; } #endregion #region Find 查询实体 /// <summary> /// 查找最大实体 /// </summary> /// <returns></returns> public virtual T Max() { return dbContext.Set<T>().Max(); } /// <summary> /// 查找最大实体(异步) /// </summary> /// <returns></returns> public async virtual Task<T> MaxAsync() { return await dbContext.Set<T>().MaxAsync(); } /// <summary> /// 查找实体(根据主键值查找) /// </summary> /// <param name="ID">实体主键值</param> /// <returns></returns> public virtual T Find(int ID) { return dbContext.Set<T>().Find(ID); } /// <summary> /// 查找实体(根据主键值查找,异步) /// </summary> /// <param name="ID">实体主键值</param> /// <returns></returns> public async virtual Task<T> FindAsync(int ID) { return await dbContext.Set<T>().FindAsync(ID); } /// <summary> /// 查找(根据联合主键) /// </summary> /// <param name="keyValues">主键</param> /// <returns></returns> public virtual T Find(object[] keyValues) { return dbContext.Set<T>().Find(keyValues); } /// <summary> /// 查找(根据联合主键,异步) /// </summary> /// <param name="keyValues">主键</param> /// <returns></returns> public virtual async Task<T> FindAsync(object[] keyValues) { return await dbContext.Set<T>().FindAsync(keyValues); } /// <summary> /// 查找实体(根据Lambda表达式) /// </summary> /// <param name="where">查询Lambda表达式</param> /// <returns></returns> public virtual T FindSingle(Expression<Func<T, bool>> where) { return dbContext.Set<T>().SingleOrDefault(where); } /// <summary> /// 查找实体(根据Lambda表达式,异步) /// </summary> /// <param name="where">查询Lambda表达式</param> /// <returns></returns> public async virtual Task<T> FindSingleAsync(Expression<Func<T, bool>> where) { return await dbContext.Set<T>().SingleOrDefaultAsync(where); } #endregion #region List 查询列表 /// <summary> /// 查询所有 /// </summary> /// <returns></returns> public virtual IQueryable<T> FindList() { return dbContext.Set<T>(); } /// <summary> /// 查询所有(异步) /// </summary> /// <returns>实体列表</returns> public virtual async Task<IQueryable<T>> FindListAsync() { IQueryable<T> result = dbContext.Set<T>(); return await Task.FromResult(result); } /// <summary> /// 查询(根据查询条件) /// </summary> /// <param name="predicate">查询条件</param> /// <returns>实体列表</returns> public virtual IQueryable<T> FindList(Expression<Func<T, bool>> predicate) { return dbContext.Set<T>().Where(predicate); } /// <summary> /// 查询(根据查询条件,异步) /// </summary> /// <param name="predicate">查询条件</param> /// <returns>实体列表</returns> public virtual async Task<IQueryable<T>> FindListAsync(Expression<Func<T, bool>> predicate) { return await Task.FromResult(FindList(predicate)); } /// <summary> /// 查询(前几条)数据(根据查询条件) /// </summary> /// <param name="number">返回记录数</param> /// <param name="predicate">查询条件</param> /// <returns>实体列表</returns> public virtual IQueryable<T> FindList(int number, Expression<Func<T, bool>> predicate) { var entityList = dbContext.Set<T>().Where(predicate); if (number > 0) return entityList.Take(number); else return entityList; } /// <summary> /// 查询(前几条)数据(根据查询条件,异步) /// </summary> /// <param name="number">返回记录数</param> /// <param name="predicate">查询条件</param> /// <returns>实体列表</returns> public virtual async Task<IQueryable<T>> FindListAsync(int number, Expression<Func<T, bool>> predicate) { return await Task.FromResult(FindList(number, predicate)); } /// <summary> /// 查询(前几条)数据(根据查询条件,带排序) /// </summary> /// <param name="number">显示数量[小于等于0-不启用]</param> /// <typeparam name="TKey">排序字段</typeparam> /// <param name="predicate">查询条件</param> /// <param name="keySelector">排序</param> /// <param name="isAsc">正序</param> /// <returns></returns> public virtual IQueryable<T> FindList<TKey>(int number, Expression<Func<T, bool>> predicate, Expression<Func<T, TKey>> keySelector, bool isAsc) { var entityList = dbContext.Set<T>().Where(predicate); if (isAsc) entityList = entityList.OrderBy(keySelector); else entityList.OrderByDescending(keySelector); if (number > 0) return entityList.Take(number); else return entityList; } /// <summary> /// 查询(前几条)数据(根据查询条件,带排序,异步) /// </summary> /// <param name="number">显示数量[小于等于0-不启用]</param> /// <typeparam name="TKey">排序字段</typeparam> /// <param name="predicate">查询条件</param> /// <param name="keySelector">排序</param> /// <param name="isAsc">正序</param> /// <returns></returns> public virtual async Task<IQueryable<T>> FindListAsync<TKey>(int number, Expression<Func<T, bool>> predicate, Expression<Func<T, TKey>> keySelector, bool isAsc) { var entityList = dbContext.Set<T>().Where(predicate); if (isAsc) entityList = entityList.OrderBy(keySelector); else entityList.OrderByDescending(keySelector); if (number > 0) entityList = entityList.Take(number); return await Task.FromResult(entityList); } #endregion #region Count 查询总数 /// <summary> /// 查询记录数 /// </summary> /// <param name="predicate">查询条件表达式</param> /// <returns>记录数</returns> public virtual int Count(Expression<Func<T, bool>> predicate) { return dbContext.Set<T>().Count(predicate); } /// <summary> /// 查询记录数(异步) /// </summary> /// <param name="predicate">查询条件表达式</param> /// <returns>记录数</returns> public virtual async Task<int> CountAsync(Expression<Func<T, bool>> predicate) { return await dbContext.Set<T>().CountAsync(predicate); } #endregion #region Exist 是否存在 /// <summary> /// 查询是否存在 /// </summary> /// <param name="predicate">查询条件表达式</param> /// <returns>是否存在</returns> public virtual bool Exists(Expression<Func<T, bool>> predicate) { return dbContext.Set<T>().Any(predicate); } /// <summary> /// 查询是否存在(异步) /// </summary> /// <param name="predicate">查询条件表达式</param> /// <returns>是否存在</returns> public virtual async Task<bool> ExistsAsync(Expression<Func<T, bool>> predicate) { return await dbContext.Set<T>().AnyAsync(predicate); } #endregion #region Page 分页查询 /// <summary> /// 查找分页列表(无条件,无排序) /// </summary> /// <param name="pageSize">每页记录数。必须大于1</param> /// <param name="pageIndex">页码。首页从1开始,页码必须大于1</param> /// <param name="totalNumber">总记录数</param> /// <returns></returns> public virtual IQueryable<T> FindPageList(int pageSize, int pageIndex, out int totalNumber) { OrderParam _orderParam = null; return FindPageList(pageSize, pageIndex, out totalNumber, _orderParam); } /// <summary> /// 查找分页列表(无条件,带排序) /// </summary> /// <param name="pageSize">每页记录数。必须大于1</param> /// <param name="pageIndex">页码。首页从1开始,页码必须大于1</param> /// <param name="totalNumber">总记录数</param> /// <param name="order">排序键</param> /// <param name="asc">是否正序</param> /// <returns></returns> public virtual IQueryable<T> FindPageList(int pageSize, int pageIndex, out int totalNumber, OrderParam orderParam) { return FindPageList(pageSize, pageIndex, out totalNumber, (T) => true, orderParam); } /// <summary> /// 查找分页列表(带条件,无排序) /// </summary> /// <param name="pageSize">每页记录数。必须大于1</param> /// <param name="pageIndex">页码。首页从1开始,页码必须大于1</param> /// <param name="totalNumber">总记录数</param> /// <param name="where">查询表达式</param> public virtual IQueryable<T> FindPageList(int pageSize, int pageIndex, out int totalNumber, Expression<Func<T, bool>> where) { OrderParam _param = null; return FindPageList(pageSize, pageIndex, out totalNumber, where, _param); } /// <summary> /// 查找分页列表(无条件,单字段排序) /// </summary> /// <param name="pageSize">每页记录数。</param> /// <param name="pageIndex">页码。首页从1开始</param> /// <param name="totalNumber">总记录数</param> /// <param name="where">查询表达式</param> /// <param name="orderParam">排序【null-不设置】</param> /// <returns></returns> public virtual IQueryable<T> FindPageList(int pageSize, int pageIndex, out int totalNumber, Expression<Func<T, bool>> where, OrderParam orderParam) { OrderParam[] _orderParams = null; if (orderParam != null) _orderParams = new OrderParam[] { orderParam }; return FindPageList(pageSize, pageIndex, out totalNumber, where, _orderParams); } /// <summary> /// 查找分页列表(带条件,带多字段排序) /// </summary> /// <param name="pageSize">每页记录数。</param> /// <param name="pageIndex">页码。首页从1开始</param> /// <param name="totalNumber">总记录数</param> /// <param name="where">查询表达式</param> /// <param name="orderParams">排序【null-不设置】</param> public virtual IQueryable<T> FindPageList(int pageSize, int pageIndex, out int totalNumber, Expression<Func<T, bool>> where, OrderParam[] orderParams) { //条件过滤 IQueryable<T> query = where == null ? dbContext.Set<T>() : dbContext.Set<T>().Where(where); //创建表达式变量参数 var parameter = Expression.Parameter(typeof(T), "o"); if (orderParams != null && orderParams.Length > 0) { for (int i = 0; i < orderParams.Length; i++) { //根据属性名获取属性 var property = typeof(T).GetProperty(orderParams[i].PropertyName); //创建一个访问属性的表达式 var propertyAccess = Expression.MakeMemberAccess(parameter, property); var orderByExp = Expression.Lambda(propertyAccess, parameter); string OrderName = ""; if (i > 0) { OrderName = orderParams[i].IsDesc ? "ThenByDescending" : "ThenBy"; } else OrderName = orderParams[i].IsDesc ? "OrderByDescending" : "OrderBy"; MethodCallExpression resultExp = Expression.Call(typeof(Queryable), OrderName, new Type[] { typeof(T), property.PropertyType }, query.Expression, Expression.Quote(orderByExp)); query = query.Provider.CreateQuery<T>(resultExp); } } totalNumber = query.Count(); return query.Skip((pageIndex - 1) * pageSize).Take(pageSize); } /// <summary> /// 查找分页列表(带条件,单字段lambda表达式排序) /// </summary> /// <typeparam name="type">排序字段类型</typeparam> /// <param name="pageSize">每页记录数</param> /// <param name="pageIndex">页码,首页从1开始</param> /// <param name="totalNumber">输出总数</param> /// <param name="isAsc">是否升序</param> /// <param name="OrderByLambda">排序条件</param> /// <param name="WhereLambda">查询条件</param> /// <returns></returns> public virtual IQueryable<T> FindPageList<type>(int pageSize, int pageIndex, out int totalNumber, bool isAsc, Expression<Func<T, type>> OrderByLambda, Expression<Func<T, bool>> WhereLambda) { //输出记录总数 totalNumber = dbContext.Set<T>().Where(WhereLambda).Count(); //是否升序 if (isAsc) { return dbContext.Set<T>().Where(WhereLambda).OrderBy(OrderByLambda).Skip((pageIndex - 1) * pageSize).Take(pageSize); } else { return dbContext.Set<T>().Where(WhereLambda).OrderByDescending(OrderByLambda).Skip((pageIndex - 1) * pageSize).Take(pageSize); } } #endregion #region Save 保存数据 /// <summary> /// 保存数据【在Add、Upate、Delete未立即保存的情况下使用】 /// </summary> /// <returns>更改的记录数</returns> public virtual int SaveChanges() { return dbContext.SaveChanges(); } /// <summary> /// 保存数据【在Add、Upate、Delete未立即保存的情况下使用】(异步) /// </summary> /// <returns>更改的记录数</returns> public virtual async Task<int> SaveChangesAsync() { return await dbContext.SaveChangesAsync(); } #endregion #region 扩展用 私有方法 /// <summary> /// 私有方法,用于更新指定列 /// </summary> /// <param name="entity">实体</param> /// <param name="properties">要修改的属性名称</param> private void UpdateRe(T entity, string[] properties = null) { var entry = dbContext.Entry(entity); if (properties == null) { entry.State = EntityState.Modified;//将所有属性标记为修改状态 } else { //Detached 对象存在,但未由对象服务跟踪。在创建实体之后、但将其添加到对象上下文之前,该实体处于此状态; if (entry.State == EntityState.Detached) entry.State = EntityState.Unchanged;//先将所有属性状态标记为未修改 foreach (var property in properties) { entry.Property(property).IsModified = true;//将要修改的属性状态标记为修改 } } } #endregion } }