ef core

using EFLogging;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace efcore.Repository
{
    public  class Repository<T> where T : class,  new()
    {
        #region 数据上下文

        /// <summary>
        /// 数据上下文
        /// </summary>
        private ApplicationDbContext _Context;

        public Repository(ApplicationDbContext Context)
        {
            _Context = Context;
        }

        #endregion

        #region 单模型 CRUD 操作


      
        /// <summary>
        /// 按照字段修改
        /// </summary>
        /// 
        ///    //M.Id = 91;
        //        M.CarNumber = "vvvvvvvvvvvvvvvv";
        //        M.CreateTime = DateTime.Now;
        //        var properties = new Expression<Func<Car, object>>[2];
        //properties[0] = d => d.CarNumber;
        //        properties[1] = d => d.CreateTime;
        //        CarBll.GetInstance().UpdateModified(M, properties);
        // 或 CarBll.GetInstance().UpdateModified(M, d => d.CarNumber, d => d.CreateTime);
        // 或  CarBll.GetInstance().UpdateModified(M, null);

        /// <param name="entity"></param>
        /// <param name="IsCommit"></param>
        /// <param name="properties"></param>
        /// <returns></returns>
        //public virtual bool UpdateModified(T entity, bool IsCommit = true, params Expression<Func<T, object>>[] properties)
        //{

        // //    _Context.Set<T>().Attach(entity);
        //   _Context.Entry(entity).State = EntityState.Unchanged;
        //    if (properties == null)
        //        {
        //            PropertyInfo[] props = entity.GetType().GetProperties();
        //            foreach (PropertyInfo prop in props)
        //            {
        //            _Context.Entry(entity).Property(prop.Name).IsModified = true;

        //            }
        //        }
        //        else
        //        {
        //            foreach (var selector in properties)
        //            {
        //            _Context.Entry(entity).Property(selector).IsModified = true;
        //            }
        //        }



         
        //    //foreach (var property in properties)
        //    //{
        //    //    var propertyName = ExpressionHelper.GetExpressionText(property);
        //    //    _context.Entry(entity).Property(propertyName).IsModified = true;
        //    //}




        //    if (IsCommit)
        //        return _Context.SaveChanges() > 0;
        //    else
        //        return false;



        //}





        /// <summary>
        /// 增加一条记录
        /// </summary>
        /// <param name="entity">实体模型</param>
        /// <param name="IsCommit">是否提交(默认提交)</param>
        /// <returns></returns>
        public virtual bool Save(T entity, bool IsCommit = true)
        {
            
            _Context.Set<T>().Add(entity);
            if (IsCommit)
                return _Context.SaveChanges() > 0;
            else
                return false;
        }
        /// <summary>
        /// 增加一条记录(异步方式)
        /// </summary>
        /// <param name="entity">实体模型</param>
        /// <param name="IsCommit">是否提交(默认提交)</param>
        /// <returns></returns>
        public virtual async Task<bool> SaveAsync(T entity, bool IsCommit = true)
        {
            _Context.Set<T>().Add(entity);
            if (IsCommit)
                return await Task.Run(() => _Context.SaveChanges() > 0);
            else
                return await Task.Run(() => false);
        }

        /// <summary>
        /// 更新一条记录
        /// </summary>
        /// <param name="entity">实体模型</param>
        /// <param name="IsCommit">是否提交(默认提交)</param>
        /// <returns></returns>
        public virtual bool Update(T entity, bool IsCommit = true)
        {
            _Context.Set<T>().Attach(entity);
            _Context.Entry<T>(entity).State = EntityState.Modified;
            if (IsCommit)
                return _Context.SaveChanges() > 0;
            else
                return false;
        }
        /// <summary>
        /// 更新一条记录(异步方式)
        /// </summary>
        /// <param name="entity">实体模型</param>
        /// <param name="IsCommit">是否提交(默认提交)</param>
        /// <returns></returns>
        public virtual async Task<bool> UpdateAsync(T entity, bool IsCommit = true)
        {
            _Context.Set<T>().Attach(entity);
            _Context.Entry<T>(entity).State = EntityState.Modified;
            if (IsCommit)
                return await Task.Run(() => _Context.SaveChanges() > 0);
            else
                return await Task.Run(() => false);
        }

        /// <summary>
        /// 增加或更新一条记录
        /// </summary>
        /// <param name="entity">实体模型</param>
        /// <param name="IsSave">是否增加</param>
        /// <param name="IsCommit">是否提交(默认提交)</param>
        /// <returns></returns>
        public virtual bool SaveOrUpdate(T entity, bool IsSave, bool IsCommit = true)
        {
            return IsSave ? Save(entity, IsCommit) : Update(entity, IsCommit);
        }
        /// <summary>
        /// 增加或更新一条记录(异步方式)
        /// </summary>
        /// <param name="entity">实体模型</param>
        /// <param name="IsSave">是否增加</param>
        /// <param name="IsCommit">是否提交(默认提交)</param>
        /// <returns></returns>
        public virtual async Task<bool> SaveOrUpdateAsync(T entity, bool IsSave, bool IsCommit = true)
        {
            return IsSave ? await SaveAsync(entity, IsCommit) : await UpdateAsync(entity, IsCommit);
        }

        /// <summary>
        /// 通过Lamda表达式获取实体
        /// </summary>
        /// <param name="predicate">Lamda表达式(p=>p.Id==Id)</param>
        /// <returns></returns>
        public virtual T Get(Expression<Func<T, bool>> predicate)
        {
            return _Context.Set<T>().AsNoTracking().SingleOrDefault(predicate);
        }
        /// <summary>
        /// 通过Lamda表达式获取实体(异步方式)
        /// </summary>
        /// <param name="predicate">Lamda表达式(p=>p.Id==Id)</param>
        /// <returns></returns>
        public virtual async Task<T> GetAsync(Expression<Func<T, bool>> predicate)
        {
            return await Task.Run(() => _Context.Set<T>().AsNoTracking().SingleOrDefault(predicate));
        }

        /// <summary>
        /// 删除一条记录
        /// </summary>
        /// <param name="entity">实体模型</param>
        /// <param name="IsCommit">是否提交(默认提交)</param>
        /// <returns></returns>
        public virtual bool Delete(T entity, bool IsCommit = true)
        {
            if (entity == null) return false;
            _Context.Set<T>().Attach(entity);
            _Context.Set<T>().Remove(entity);

            if (IsCommit)
                return _Context.SaveChanges() > 0;
            else
                return false;
        }
        /// <summary>
        /// 删除一条记录(异步方式)
        /// </summary>
        /// <param name="entity">实体模型</param>
        /// <param name="IsCommit">是否提交(默认提交)</param>
        /// <returns></returns>
        public virtual async Task<bool> DeleteAsync(T entity, bool IsCommit = true)
        {
            if (entity == null) return await Task.Run(() => false);
            _Context.Set<T>().Attach(entity);
            _Context.Set<T>().Remove(entity);
            if (IsCommit)
                return await Task.Run(() => _Context.SaveChanges() > 0);
            else
                return await Task.Run(() => false); ;
        }

        #endregion

        #region 多模型 操作

        /// <summary>
        /// 增加多条记录,同一模型
        /// </summary>
        /// <param name="T1">实体模型集合</param>
        /// <param name="IsCommit">是否提交(默认提交)</param>
        /// <returns></returns>
        public virtual bool SaveList(List<T> T1, bool IsCommit = true)
        {
            if (T1 == null || T1.Count == 0) return false;

            T1.ToList().ForEach(item =>
            {
                _Context.Set<T>().Add(item);
            });

            if (IsCommit)
                return _Context.SaveChanges() > 0;
            else
                return false;
        }
        /// <summary>
        /// 增加多条记录,同一模型(异步方式)
        /// </summary>
        /// <param name="T1">实体模型集合</param>
        /// <param name="IsCommit">是否提交(默认提交)</param>
        /// <returns></returns>
        public virtual async Task<bool> SaveListAsync(List<T> T1, bool IsCommit = true)
        {
            if (T1 == null || T1.Count == 0) return await Task.Run(() => false);

            T1.ToList().ForEach(item =>
            {
                _Context.Set<T>().Add(item);
            });

            if (IsCommit)
                return await Task.Run(() => _Context.SaveChanges() > 0);
            else
                return await Task.Run(() => false);
        }

        /// <summary>
        /// 增加多条记录,独立模型
        /// </summary>
        /// <param name="T1">实体模型集合</param>
        /// <param name="IsCommit">是否提交(默认提交)</param>
        /// <returns></returns>
        public virtual bool SaveList<T1>(List<T1> T, bool IsCommit = true) where T1 : class
        {
            if (T == null || T.Count == 0) return false;
            var tmp = _Context.ChangeTracker.Entries<T>().ToList();
            foreach (var x in tmp)
            {
                var properties = typeof(T).GetTypeInfo().GetProperties();
                foreach (var y in properties)
                {
                    var entry = x.Property(y.Name);
                    entry.CurrentValue = entry.OriginalValue;
                    entry.IsModified = false;
                    y.SetValue(x.Entity, entry.OriginalValue);
                }
                x.State = EntityState.Unchanged;
            }
            T.ToList().ForEach(item =>
            {
                _Context.Set<T1>().Add(item);
            });
            if (IsCommit)
                return _Context.SaveChanges() > 0;
            else
                return false;
        }
        /// <summary>
        /// 增加多条记录,独立模型(异步方式)
        /// </summary>
        /// <param name="T1">实体模型集合</param>
        /// <param name="IsCommit">是否提交(默认提交)</param>
        /// <returns></returns>
        public virtual async Task<bool> SaveListAsync<T1>(List<T1> T, bool IsCommit = true) where T1 : class
        {
            if (T == null || T.Count == 0) return await Task.Run(() => false);
            var tmp = _Context.ChangeTracker.Entries<T>().ToList();
            foreach (var x in tmp)
            {
                var properties = typeof(T).GetTypeInfo().GetProperties();
                foreach (var y in properties)
                {
                    var entry = x.Property(y.Name);
                    entry.CurrentValue = entry.OriginalValue;
                    entry.IsModified = false;
                    y.SetValue(x.Entity, entry.OriginalValue);
                }
                x.State = EntityState.Unchanged;
            }
            T.ToList().ForEach(item =>
            {
                _Context.Set<T1>().Add(item);
            });
            if (IsCommit)
                return await Task.Run(() => _Context.SaveChanges() > 0);
            else
                return await Task.Run(() => false);
        }

        /// <summary>
        /// 更新多条记录,同一模型
        /// </summary>
        /// <param name="T1">实体模型集合</param>
        /// <param name="IsCommit">是否提交(默认提交)</param>
        /// <returns></returns>
        public virtual bool UpdateList(List<T> T1, bool IsCommit = true)
        {
            if (T1 == null || T1.Count == 0) return false;

            T1.ToList().ForEach(item =>
            {
                _Context.Set<T>().Attach(item);
                _Context.Entry<T>(item).State = EntityState.Modified;
            });

            if (IsCommit)
                return _Context.SaveChanges() > 0;
            else
                return false;
        }
        /// <summary>
        /// 更新多条记录,同一模型(异步方式)
        /// </summary>
        /// <param name="T1">实体模型集合</param>
        /// <param name="IsCommit">是否提交(默认提交)</param>
        /// <returns></returns>
        public virtual async Task<bool> UpdateListAsync(List<T> T1, bool IsCommit = true)
        {
            if (T1 == null || T1.Count == 0) return await Task.Run(() => false);

            T1.ToList().ForEach(item =>
            {
                _Context.Set<T>().Attach(item);
                _Context.Entry<T>(item).State = EntityState.Modified;
            });

            if (IsCommit)
                return await Task.Run(() => _Context.SaveChanges() > 0);
            else
                return await Task.Run(() => false);
        }

        /// <summary>
        /// 更新多条记录,独立模型
        /// </summary>
        /// <param name="T1">实体模型集合</param>
        /// <param name="IsCommit">是否提交(默认提交)</param>
        /// <returns></returns>
        public virtual bool UpdateList<T1>(List<T1> T, bool IsCommit = true) where T1 : class
        {
            if (T == null || T.Count == 0) return false;

            T.ToList().ForEach(item =>
            {
                _Context.Set<T1>().Attach(item);
                _Context.Entry<T1>(item).State = EntityState.Modified;
            });

            if (IsCommit)
                return _Context.SaveChanges() > 0;
            else
                return false;
        }
        /// <summary>
        /// 更新多条记录,独立模型(异步方式)
        /// </summary>
        /// <param name="T1">实体模型集合</param>
        /// <param name="IsCommit">是否提交(默认提交)</param>
        /// <returns></returns>
        public virtual async Task<bool> UpdateListAsync<T1>(List<T1> T, bool IsCommit = true) where T1 : class
        {
            if (T == null || T.Count == 0) return await Task.Run(() => false);

            T.ToList().ForEach(item =>
            {
                _Context.Set<T1>().Attach(item);
                _Context.Entry<T1>(item).State = EntityState.Modified;
            });

            if (IsCommit)
                return await Task.Run(() => _Context.SaveChanges() > 0);
            else
                return await Task.Run(() => false);
        }

        /// <summary>
        /// 删除多条记录,同一模型
        /// </summary>
        /// <param name="T1">实体模型集合</param>
        /// <param name="IsCommit">是否提交(默认提交)</param>
        /// <returns></returns>
        public virtual bool DeleteList(List<T> T1, bool IsCommit = true)
        {
            if (T1 == null || T1.Count == 0) return false;

            T1.ToList().ForEach(item =>
            {
                _Context.Set<T>().Attach(item);
                _Context.Set<T>().Remove(item);
            });

            if (IsCommit)
                return _Context.SaveChanges() > 0;
            else
                return false;
        }
        /// <summary>
        /// 删除多条记录,同一模型(异步方式)
        /// </summary>
        /// <param name="T1">实体模型集合</param>
        /// <param name="IsCommit">是否提交(默认提交)</param>
        /// <returns></returns>
        public virtual async Task<bool> DeleteListAsync(List<T> T1, bool IsCommit = true)
        {
            if (T1 == null || T1.Count == 0) return await Task.Run(() => false);

            T1.ToList().ForEach(item =>
            {
                _Context.Set<T>().Attach(item);
                _Context.Set<T>().Remove(item);
            });

            if (IsCommit)
                return await Task.Run(() => _Context.SaveChanges() > 0);
            else
                return await Task.Run(() => false);
        }

        /// <summary>
        /// 删除多条记录,独立模型
        /// </summary>
        /// <param name="T1">实体模型集合</param>
        /// <param name="IsCommit">是否提交(默认提交)</param>
        /// <returns></returns>
        public virtual bool DeleteList<T1>(List<T1> T, bool IsCommit = true) where T1 : class
        {
            if (T == null || T.Count == 0) return false;

            T.ToList().ForEach(item =>
            {
                _Context.Set<T1>().Attach(item);
                _Context.Set<T1>().Remove(item);
            });

            if (IsCommit)
                return _Context.SaveChanges() > 0;
            else
                return false;
        }
        /// <summary>
        /// 删除多条记录,独立模型(异步方式)
        /// </summary>
        /// <param name="T1">实体模型集合</param>
        /// <param name="IsCommit">是否提交(默认提交)</param>
        /// <returns></returns>
        public virtual async Task<bool> DeleteListAsync<T1>(List<T1> T, bool IsCommit = true) where T1 : class
        {
            if (T == null || T.Count == 0) return await Task.Run(() => false);

            T.ToList().ForEach(item =>
            {
                _Context.Set<T1>().Attach(item);
                _Context.Set<T1>().Remove(item);
            });

            if (IsCommit)
                return await Task.Run(() => _Context.SaveChanges() > 0);
            else
                return await Task.Run(() => false);
        }

        /// <summary>
        /// 通过Lamda表达式,删除一条或多条记录
        /// </summary>
        /// <param name="predicate"></param>
        /// <param name="IsCommit"></param>
        /// <returns></returns>
        public virtual bool Delete(Expression<Func<T, bool>> predicate, bool IsCommit = true)
        {
            IQueryable<T> entry = (predicate == null) ? _Context.Set<T>().AsQueryable() : _Context.Set<T>().Where(predicate);
            List<T> list = entry.ToList();

            if (list != null && list.Count == 0) return false;
            list.ForEach(item => {
                _Context.Set<T>().Attach(item);
                _Context.Set<T>().Remove(item);
            });

            if (IsCommit)
                return _Context.SaveChanges() > 0;
            else
                return false;
        }
        /// <summary>
        /// 通过Lamda表达式,删除一条或多条记录(异步方式)
        /// </summary>
        /// <param name="predicate"></param>
        /// <param name="IsCommit"></param>
        /// <returns></returns>
        public virtual async Task<bool> DeleteAsync(Expression<Func<T, bool>> predicate, bool IsCommit = true)
        {
            IQueryable<T> entry = (predicate == null) ? _Context.Set<T>().AsQueryable() : _Context.Set<T>().Where(predicate);
            List<T> list = entry.ToList();

            if (list != null && list.Count == 0) return await Task.Run(() => false);
            list.ForEach(item => {
                _Context.Set<T>().Attach(item);
                _Context.Set<T>().Remove(item);
            });

            if (IsCommit)
                return await Task.Run(() => _Context.SaveChanges() > 0);
            else
                return await Task.Run(() => false);
        }

        #endregion

        #region 获取多条数据操作


        /// <summary>
        /// linq 分页
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="whereQuery">条件</param>
        /// <param name="orderQuery">排序</param>
        /// <param name="pageID">页码</param>
        /// <param name="pageSizes">每页条数</param>
        ///   /// <param name="selector">查询字段 默认 为空 全部</param>
        /// <returns></returns>
        public virtual PagedynamicResult<T> GetLinqPage<TKey>(Expression<Func<T, bool>> whereQuery, QueryableOrderEntry<T, TKey> orderQuery, int pageID, int pageSizes)
        {
            //  pageID = pageID < 1 ? 0 : pageID - 1;
            List<T > data = new List<T >();

            var query = _Context.Set<T>().Where(whereQuery);// repository.TableNoTracking.Where(whereQuery);
            int count = query.Count();
            //if (selector != null)
            //{
            //    if (orderQuery.OrderDirection == OrderDirection.DESC)
            //    {
            //        data = query.OrderByDescending(orderQuery.Expression).Select(selector)
            //            .Skip(pageSizes * pageID)
            //            .Take(pageSizes).ToList();
            //    }
            //    else
            //    {
            //        data = query
            //            .OrderBy(orderQuery.Expression).Select(selector)
            //            .Skip(pageSizes * pageID)
            //            .Take(pageSizes).ToList();
            //    }
            //}
            //else
            //{
                if (orderQuery.OrderDirection == OrderDirection.DESC)
                {
                    data = query.OrderByDescending(orderQuery.Expression)
                        .Skip(pageSizes * pageID)
                        .Take(pageSizes).ToList<T>();
                }
                else
                {
                    data = query
                        .OrderBy(orderQuery.Expression)
                        .Skip(pageSizes * pageID)
                        .Take(pageSizes).ToList<T>();
                }
            //}



           // var serviceProvider = _Context.GetInfrastructure<IServiceProvider>();
           // var loggerFactory = serviceProvider.GetService<ILoggerFactory>();
          //  loggerFactory.AddProvider(new MyLoggerProvider());


            return new PagedynamicResult<T> { Data = data, ItemCount = count, PageSize = pageSizes, PageIndex = pageID + 1 };
        }



        /// <summary>
        /// Lamda返回IQueryable集合,延时加载数据
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public virtual IQueryable<T> LoadAll(Expression<Func<T, bool>> predicate)
        {
            return predicate != null ? _Context.Set<T>().Where(predicate).AsNoTracking<T>() : _Context.Set<T>().AsQueryable<T>().AsNoTracking<T>();
        }
        /// <summary>
        /// 返回IQueryable集合,延时加载数据(异步方式)
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public virtual async Task<IQueryable<T>> LoadAllAsync(Expression<Func<T, bool>> predicate)
        {
            return predicate != null ? await Task.Run(() => _Context.Set<T>().Where(predicate).AsNoTracking<T>()) : await Task.Run(() => _Context.Set<T>().AsQueryable<T>().AsNoTracking<T>());
        }

        /// <summary>
        /// 返回List<T>集合,不采用延时加载
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public virtual List<T> LoadListAll(Expression<Func<T, bool>> predicate)
        {
            return predicate != null ? _Context.Set<T>().Where(predicate).AsNoTracking().ToList() : _Context.Set<T>().AsQueryable<T>().AsNoTracking().ToList();
        }
        // <summary>
        /// 返回List<T>集合,不采用延时加载(异步方式)
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public virtual async Task<List<T>> LoadListAllAsync(Expression<Func<T, bool>> predicate)
        {
            return predicate != null ? await Task.Run(() => _Context.Set<T>().Where(predicate).AsNoTracking().ToList()) : await Task.Run(() => _Context.Set<T>().AsQueryable<T>().AsNoTracking().ToList());
        }

        /// <summary>
        /// T-Sql方式:返回IQueryable<T>集合
        /// </summary>
        /// <param name="sql">SQL语句</param>
        /// <param name="para">Parameters参数</param>
        /// <returns></returns>
        public virtual IQueryable<T> LoadAllBySql(string sql, params DbParameter[] para)
        {
            return _Context.Set<T>().FromSql(sql, para);
        }
        /// <summary>
        /// T-Sql方式:返回IQueryable<T>集合(异步方式)
        /// </summary>
        /// <param name="sql">SQL语句</param>
        /// <param name="para">Parameters参数</param>
        /// <returns></returns>
        public virtual async Task<IQueryable<T>> LoadAllBySqlAsync(string sql, params DbParameter[] para)
        {
            return await Task.Run(() => _Context.Set<T>().FromSql(sql, para));
        }


        /// <summary>
        /// T-Sql方式:返回List<T>集合
        /// </summary>
        /// <param name="sql">SQL语句</param>
        /// <param name="para">Parameters参数</param>
        /// <returns></returns>
        public virtual List<T> LoadListAllBySql(string sql, params DbParameter[] para)
        {
            return _Context.Set<T>().FromSql(sql, para).Cast<T>().ToList();
        }
        /// <summary>
        /// T-Sql方式:返回List<T>集合(异步方式)
        /// </summary>
        /// <param name="sql">SQL语句</param>
        /// <param name="para">Parameters参数</param>
        /// <returns></returns>
        public virtual async Task<List<T>> LoadListAllBySqlAsync(string sql, params DbParameter[] para)
        {
            return await Task.Run(() => _Context.Set<T>().FromSql(sql, para).Cast<T>().ToList());
        }

        /// <summary>
        /// 可指定返回结果、排序、查询条件的通用查询方法,返回实体对象集合
        /// </summary>
        /// <typeparam name="TEntity">实体对象</typeparam>
        /// <typeparam name="TOrderBy">排序字段类型</typeparam>
        /// <typeparam name="TResult">数据结果,与TEntity一致</typeparam>
        /// <param name="where">过滤条件,需要用到类型转换的需要提前处理与数据表一致的</param>
        /// <param name="orderby">排序字段</param>
        /// <param name="selector">返回结果(必须是模型中存在的字段)</param>
        /// <param name="IsAsc">排序方向,true为正序false为倒序</param>
        /// <returns>实体集合</returns>
        //public virtual List<TResult> QueryEntity<TEntity, TOrderBy, TResult>
        //    (Expression<Func<TEntity, bool>> where,
        //    Expression<Func<TEntity, TOrderBy>> orderby,
        //    Expression<Func<TEntity, TResult>> selector,
        //    bool IsAsc)
        //    where TEntity : class
        //    where TResult : class
        //{
        //    IQueryable<TEntity> query = _Context.Set<TEntity>();
        //    if (where != null)
        //    {
        //        query = query.Where(where);
        //    }

        //    if (orderby != null)
        //    {
        //        query = IsAsc ? query.OrderBy(orderby) : query.OrderByDescending(orderby);
        //    }
        //    if (selector == null)
        //    {
        //        return query.Cast<TResult>().AsNoTracking().ToList();
        //    }
        //    return query.Select(selector).AsNoTracking().ToList();
        //}
        /// <summary>
        /// 可指定返回结果、排序、查询条件的通用查询方法,返回实体对象集合(异步方式)
        /// </summary>
        /// <typeparam name="TEntity">实体对象</typeparam>
        /// <typeparam name="TOrderBy">排序字段类型</typeparam>
        /// <typeparam name="TResult">数据结果,与TEntity一致</typeparam>
        /// <param name="where">过滤条件,需要用到类型转换的需要提前处理与数据表一致的</param>
        /// <param name="orderby">排序字段</param>
        /// <param name="selector">返回结果(必须是模型中存在的字段)</param>
        /// <param name="IsAsc">排序方向,true为正序false为倒序</param>
        /// <returns>实体集合</returns>
        //public virtual async Task<List<TResult>> QueryEntityAsync<TEntity, TOrderBy, TResult>
        //    (Expression<Func<TEntity, bool>> where,
        //    Expression<Func<TEntity, TOrderBy>> orderby,
        //    Expression<Func<TEntity, TResult>> selector,
        //    bool IsAsc)
        //    where TEntity : class
        //    where TResult : class
        //{
        //    IQueryable<TEntity> query = _Context.Set<TEntity>();
        //    if (where != null)
        //    {
        //        query = query.Where(where);
        //    }

        //    if (orderby != null)
        //    {
        //        query = IsAsc ? query.OrderBy(orderby) : query.OrderByDescending(orderby);
        //    }
        //    if (selector == null)
        //    {
        //        return await Task.Run(() => query.Cast<TResult>().AsNoTracking().ToList());
        //    }
        //    return await Task.Run(() => query.Select(selector).AsNoTracking().ToList());
        //}

        /// <summary>
        /// 可指定返回结果、排序、查询条件的通用查询方法,返回Object对象集合
        /// </summary>
        /// <typeparam name="TEntity">实体对象</typeparam>
        /// <typeparam name="TOrderBy">排序字段类型</typeparam>
        /// <param name="where">过滤条件,需要用到类型转换的需要提前处理与数据表一致的</param>
        /// <param name="orderby">排序字段</param>
        /// <param name="selector">返回结果(必须是模型中存在的字段)</param>
        /// <param name="IsAsc">排序方向,true为正序false为倒序</param>
        /// <returns>自定义实体集合</returns>
        //public virtual List<object> QueryObject<TEntity, TOrderBy>
        //    (Expression<Func<TEntity, bool>> where,
        //    Expression<Func<TEntity, TOrderBy>> orderby,
        //    Func<IQueryable<TEntity>,
        //    List<object>> selector,
        //    bool IsAsc)
        //    where TEntity : class
        //{
        //    IQueryable<TEntity> query = _Context.Set<TEntity>();
        //    if (where != null)
        //    {
        //        query = query.Where(where);
        //    }

        //    if (orderby != null)
        //    {
        //        query = IsAsc ? query.OrderBy(orderby) : query.OrderByDescending(orderby);
        //    }
        //    if (selector == null)
        //    {
        //        return query.AsNoTracking().ToList<object>();
        //    }
        //    return selector(query);
        //}
        /// <summary>
        /// 可指定返回结果、排序、查询条件的通用查询方法,返回Object对象集合(异步方式)
        /// </summary>
        /// <typeparam name="TEntity">实体对象</typeparam>
        /// <typeparam name="TOrderBy">排序字段类型</typeparam>
        /// <param name="where">过滤条件,需要用到类型转换的需要提前处理与数据表一致的</param>
        /// <param name="orderby">排序字段</param>
        /// <param name="selector">返回结果(必须是模型中存在的字段)</param>
        /// <param name="IsAsc">排序方向,true为正序false为倒序</param>
        /// <returns>自定义实体集合</returns>
        //public virtual async Task<List<object>> QueryObjectAsync<TEntity, TOrderBy>
        //    (Expression<Func<TEntity, bool>> where,
        //    Expression<Func<TEntity, TOrderBy>> orderby,
        //    Func<IQueryable<TEntity>,
        //    List<object>> selector,
        //    bool IsAsc)
        //    where TEntity : class
        //{
        //    IQueryable<TEntity> query = _Context.Set<TEntity>();
        //    if (where != null)
        //    {
        //        query = query.Where(where);
        //    }

        //    if (orderby != null)
        //    {
        //        query = IsAsc ? query.OrderBy(orderby) : query.OrderByDescending(orderby);
        //    }
        //    if (selector == null)
        //    {
        //        return await Task.Run(() => query.AsNoTracking().ToList<object>());
        //    }
        //    return await Task.Run(() => selector(query));
        //}


        /// <summary>
        /// 可指定返回结果、排序、查询条件的通用查询方法,返回动态类对象集合
        /// </summary>
        /// <typeparam name="TEntity">实体对象</typeparam>
        /// <typeparam name="TOrderBy">排序字段类型</typeparam>
        /// <param name="where">过滤条件,需要用到类型转换的需要提前处理与数据表一致的</param>
        /// <param name="orderby">排序字段</param>
        /// <param name="selector">返回结果(必须是模型中存在的字段)</param>
        /// <param name="IsAsc">排序方向,true为正序false为倒序</param>
        /// <returns>动态类</returns>
        //public virtual dynamic QueryDynamic<TEntity, TOrderBy>
        //    (Expression<Func<TEntity, bool>> where,
        //    Expression<Func<TEntity, TOrderBy>> orderby,
        //    Func<IQueryable<TEntity>,
        //    List<object>> selector,
        //    bool IsAsc)
        //    where TEntity : class
        //{
        //    List<object> list = QueryObject<TEntity, TOrderBy>
        //         (where, orderby, selector, IsAsc);
        //    return  Common.JsonHelper.JsonConvert.JsonClass(list);
        //}
        /// <summary>
        /// 可指定返回结果、排序、查询条件的通用查询方法,返回动态类对象集合(异步方式)
        /// </summary>
        /// <typeparam name="TEntity">实体对象</typeparam>
        /// <typeparam name="TOrderBy">排序字段类型</typeparam>
        /// <param name="where">过滤条件,需要用到类型转换的需要提前处理与数据表一致的</param>
        /// <param name="orderby">排序字段</param>
        /// <param name="selector">返回结果(必须是模型中存在的字段)</param>
        /// <param name="IsAsc">排序方向,true为正序false为倒序</param>
        /// <returns>动态类</returns>
        //public virtual async Task<dynamic> QueryDynamicAsync<TEntity, TOrderBy>
        //    (Expression<Func<TEntity, bool>> where,
        //    Expression<Func<TEntity, TOrderBy>> orderby,
        //    Func<IQueryable<TEntity>,
        //    List<object>> selector,
        //    bool IsAsc)
        //    where TEntity : class
        //{
        //    List<object> list = QueryObject<TEntity, TOrderBy>
        //         (where, orderby, selector, IsAsc);
           
        //  return await Task.Run(() => Common.JsonHelper.JsonConvert.JsonClass(list));
        //}

        #endregion

        #region 验证是否存在

        /// <summary>
        /// 验证当前条件是否存在相同项
        /// </summary>
        public virtual bool IsExist(Expression<Func<T, bool>> predicate)
        {
            var entry = _Context.Set<T>().Where(predicate);
            return (entry.Any());
        }
        /// <summary>
        /// 验证当前条件是否存在相同项(异步方式)
        /// </summary>
        public virtual async Task<bool> IsExistAsync(Expression<Func<T, bool>> predicate)
        {
            var entry = _Context.Set<T>().Where(predicate);
            return await Task.Run(() => entry.Any());
        }

        /// <summary>
        /// 根据SQL验证实体对象是否存在
        /// </summary>
        public virtual bool IsExist(string sql, params DbParameter[] para)
        {
            return _Context.Database.ExecuteSqlCommand(sql, para) > 0;
        }
        /// <summary>
        /// 根据SQL验证实体对象是否存在(异步方式)
        /// </summary>
        public virtual async Task<bool> IsExistAsync(string sql, params DbParameter[] para)
        {
            return await Task.Run(() => _Context.Database.ExecuteSqlCommand(sql, para) > 0);
        }

        #endregion

    }
}

  

using System;
using System.Collections.Generic;
using System.Text;

namespace efcore.Repository
{
    /// <summary>
    /// Describe:工作单元实现类
    /// Author:yuangang
    /// Date:2016/07/16
    /// Blogs:http://www.cnblogs.com/yuangang
    /// </summary>
    public class UnitOfWork : IUnitOfWork, IDisposable
    {
        #region 数据上下文

        /// <summary>
        /// 数据上下文
        /// </summary>
        private ApplicationDbContext _Context;
        public UnitOfWork(ApplicationDbContext Context)
        {
            _Context = Context;
        }

        #endregion

     



        public bool Commit()
        {
            return _Context.SaveChanges() > 0;
        }

        public void Dispose()
        {
            if (_Context != null)
            {
                _Context.Dispose();
            }
            GC.SuppressFinalize(this);
        }
    }
}

  

using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Data.Common;
using Microsoft.Extensions.Logging;

namespace efcore.Repository
{
    public class ApplicationDbContext : DbContext
    {

       // private readonly ILogger _logger;
        private readonly ILoggerFactory _logger;
        public ApplicationDbContext(ILoggerFactory _loggerFactory, DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {
            // var fff=   base.Database.ToString();
            // options. ProviderManifestToken

           // _logger = _loggerFactory.CreateLogger<ApplicationDbContext>();
            _logger = _loggerFactory
                ;

        }


        public DbSet<SYS_USER> SYS_USER { get; set; }

        public DbSet<tt> tt { get; set; }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);
        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            base.OnConfiguring(optionsBuilder);

            optionsBuilder.UseLoggerFactory(_logger);
        }

    }

    //#region DbCommandInterceptor拦截生成的SQL语句
    //class EFIntercepterLogging : DbCommandInterceptor
    //{
    //    private readonly Stopwatch _stopwatch = new Stopwatch();
    //    public override void ScalarExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
    //    {
    //        base.ScalarExecuting(command, interceptionContext);
    //        _stopwatch.Restart();
    //    }
    //    public override void ScalarExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
    //    {
    //        _stopwatch.Stop();
    //        if (interceptionContext.Exception != null)
    //        {
    //            Trace.TraceError("Exception:{1} 
 --> Error executing command: {0}", command.CommandText, interceptionContext.Exception.ToString());
    //        }
    //        else
    //        {
    //            Trace.TraceInformation("
执行时间:{0} 毫秒
-->ScalarExecuted.Command:{1}
", _stopwatch.ElapsedMilliseconds, command.CommandText);
    //        }
    //        base.ScalarExecuted(command, interceptionContext);
    //    }
    //    public override void NonQueryExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
    //    {
    //        base.NonQueryExecuting(command, interceptionContext);
    //        _stopwatch.Restart();
    //    }
    //    public override void NonQueryExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
    //    {
    //        _stopwatch.Stop();
    //        if (interceptionContext.Exception != null)
    //        {
    //            Trace.TraceError("Exception:{1} 
 --> Error executing command:
 {0}", command.CommandText, interceptionContext.Exception.ToString());
    //        }
    //        else
    //        {
    //            Trace.TraceInformation("
执行时间:{0} 毫秒
-->NonQueryExecuted.Command:
{1}", _stopwatch.ElapsedMilliseconds, command.CommandText);
    //        }
    //        base.NonQueryExecuted(command, interceptionContext);
    //    }
    //    public override void ReaderExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<System.Data.Common.DbDataReader> interceptionContext)
    //    {
    //        base.ReaderExecuting(command, interceptionContext);
    //        _stopwatch.Restart();
    //    }
    //    public override void ReaderExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<System.Data.Common.DbDataReader> interceptionContext)
    //    {
    //        _stopwatch.Stop();
    //        if (interceptionContext.Exception != null)
    //        {
    //            Trace.TraceError("Exception:{1} 
 --> Error executing command:
 {0}", command.CommandText, interceptionContext.Exception.ToString());
    //        }
    //        else
    //        {
    //            Trace.TraceInformation("
执行时间:{0} 毫秒 
 -->ReaderExecuted.Command:
{1}", _stopwatch.ElapsedMilliseconds, command.CommandText);
    //        }
    //        base.ReaderExecuted(command, interceptionContext);
    //    }
    //}
    //#endregion

    public class PagedynamicResult<dynamic>
    {
        public int ItemCount { get; set; }
        public int PageIndex { get; set; }
        public int PageSize { get; set; }
        public int PageCount
        {
            get
            {
                try
                {
                    int m = ItemCount % PageSize;
                    if (m == 0)
                        return ItemCount / PageSize;
                    else
                        return ItemCount / PageSize + 1;
                }
                catch
                {
                    return 0;
                }
            }
        }
        public List<dynamic> Data { get; set; }
    }

    /// <summary>
    /// 分页返回数据
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class PageResult<T>
    {
        public int ItemCount { get; set; }
        public int PageIndex { get; set; }
        public int PageSize { get; set; }
        public int PageCount
        {
            get
            {
                try
                {
                    int m = ItemCount % PageSize;
                    if (m == 0)
                        return ItemCount / PageSize;
                    else
                        return ItemCount / PageSize + 1;
                }
                catch
                {
                    return 0;
                }
            }
        }

        public List<T> Data { get; set; }
    }



   



    #region 查询条件扩展


    public static class PredicateBuilder
    {



        /// <summary>
        /// Convert a lambda expression for a getter into a setter
        /// </summary>
        public static Action<T, TProperty> GetSetter<T, TProperty>(Expression<Func<T, TProperty>> expression)
        {
            var memberExpression = (MemberExpression)expression.Body;
            var property = (PropertyInfo)memberExpression.Member;
            var setMethod = property.GetSetMethod();

            var parameterT = Expression.Parameter(typeof(T), "x");
            var parameterTProperty = Expression.Parameter(typeof(TProperty), "y");

            var newExpression =
                Expression.Lambda<Action<T, TProperty>>(
                    Expression.Call(parameterT, setMethod, parameterTProperty),
                    parameterT,
                    parameterTProperty
                );

            return newExpression.Compile();
        }



        public static Expression<Func<T, bool>> True<T>() { return f => true; }
        public static Expression<Func<T, bool>> False<T>() { return f => false; }
        public static Expression<T> Compose<T>(this Expression<T> first, Expression<T> second, Func<Expression, Expression, Expression> merge)
        {
            // build parameter map (from parameters of second to parameters of first)  
            var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f);

            // replace parameters in the second lambda expression with parameters from the first  
            var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);

            // apply composition of lambda expression bodies to parameters from the first expression   
            return Expression.Lambda<T>(merge(first.Body, secondBody), first.Parameters);
        }

        public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
        {
            return first.Compose(second, Expression.And);
        }

        public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
        {
            return first.Compose(second, Expression.Or);
        }
    }

    public class ParameterRebinder : ExpressionVisitor
    {
        private readonly Dictionary<ParameterExpression, ParameterExpression> map;

        public ParameterRebinder(Dictionary<ParameterExpression, ParameterExpression> map)
        {
            this.map = map ?? new Dictionary<ParameterExpression, ParameterExpression>();
        }

        public static Expression ReplaceParameters(Dictionary<ParameterExpression, ParameterExpression> map, Expression exp)
        {
            return new ParameterRebinder(map).Visit(exp);
        }

        protected override Expression VisitParameter(ParameterExpression p)
        {
            ParameterExpression replacement;
            if (map.TryGetValue(p, out replacement))
            {
                p = replacement;
            }
            return base.VisitParameter(p);
        }
    }
    #endregion

    #region 排序扩展
    public class QueryableOrderEntry<TSource, TKey>
    {

        public QueryableOrderEntry(Expression<Func<TSource, TKey>> expression)
        {
            this.Expression = expression;
            OrderDirection = OrderDirection.ASC;
        }

        public QueryableOrderEntry(Expression<Func<TSource, TKey>> expression, OrderDirection orderDirection)
        {
            this.Expression = expression;
            OrderDirection = orderDirection;
        }

        public Expression<Func<TSource, TKey>> Expression
        {
            get;
            set;
        }

        public OrderDirection OrderDirection
        {
            get;
            set;
        }
    }
    public enum OrderDirection
    {
        ASC, DESC
    }
    #endregion

}

  

   services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("SqlServerConnection"), b => b.UseRowNumberForPaging()));

  

原文地址:https://www.cnblogs.com/lyl6796910/p/6726169.html