園子裏已有挺多博文介紹了EFCore+Mysql/MSSql如何進行使用,但實際開發不會把EF層放在Web層混合起來,須要多個項目配合結構清晰的進行分層工做,本文根據我的實踐經驗總結將各個項目進行分層,僅供想本身搭建,包含數據倉儲以及分頁多字段排序。html
新建.NetCore類庫項目Entity,本人使用的是2.0的SDKgit
PM> Install-Package Microsoft.AspNetCore.All -version 2.0.9
PM> Install-Package Pomelo.EntityFrameworkCore.MySql -version 2.0.1
父類EntityBasegithub
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Text; namespace Entity.Table { public class EntityBase { /// <summary> /// 建立時間 /// </summary> [Display(Name = "建立時間")] public DateTime? CreateTime { get; set; } = DateTime.Now; /// <summary> /// 建立人 /// </summary> [Display(Name = "建立人")] [StringLength(32)] public string CreateUser { get; set; } /// <summary> /// 狀態0-刪除,1-正常,2-禁用,3-待審覈 /// </summary> [Display(Name = "狀態0-邏輯刪除,1-正常,2-禁用,...")] public virtual int? Status { get; set; } = 2; /// <summary> /// 排序 /// </summary> [Display(Name = "排序")] public int? Sort { get; set; } = 0; /// <summary> /// 備註 /// </summary> [Display(Name = "備註")] [StringLength(200)] public string Remark { get; set; } = ""; } }
實體類SysUserweb
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Text; namespace Entity.Table { [Table("Sys_User")] public class SysUser : EntityBase { [Key] [StringLength(32)] public string SysUserId { get; set; } [Display(Name = "用戶名")] [Required] [StringLength(32)] public string UserName { get; set; } [Display(Name = "密碼")] [StringLength(255)] public string Password { get; set; } [Display(Name = "真實姓名")] [StringLength(32)] public string TrueName { get; set; } [Display(Name = "暱稱")] [StringLength(32)] public string NikeName { get; set; } [Display(Name = "手機號")] [StringLength(20)] public string Mobile { get; set; } [Display(Name = "郵箱")] [EmailAddress] [StringLength(100)] public string Email { get; set; } [Display(Name = "QQOpenid")] [StringLength(200)] public string QQ { get; set; } [Display(Name = "微信openid")] [StringLength(200)] public string WX { get; set; } [Display(Name = "頭像")] [StringLength(255)] public string Avatar { get; set; } [Display(Name = "性別")] [StringLength(1)] public string Sex { get; set; } [Display(Name = "用戶類型")] [StringLength(1)] public string UserType { get; set; }//0-前臺用戶,1-管理用戶 } }
using Entity.Table; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using System; namespace Entity { public class AeDbContext : DbContext { #region 構造方法 public AeDbContext(DbContextOptions<AeDbContext> options) : base(options) { } public AeDbContext() { } //非注入構造方式 #endregion #region 表對象 public virtual DbSet<SysUser> SysUsers { get; set; } #endregion protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { base.OnConfiguring(optionsBuilder); if (!optionsBuilder.IsConfigured) { //重點:數據遷移或者直接New AeDbContext時候用到的連接字符串獲取方式 var builder = new ConfigurationBuilder() .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); var configuration = builder.Build(); string connectionString = configuration.GetConnectionString("SQLConnection"); optionsBuilder.UseMySql(connectionString); } } } }
在這有重寫OnConfiguring方法,若是沒有構造數據庫連接字符串的話則到appsettings.json中去取,注意將appsettings.json文件始終複製sql
appsettings.json數據庫
{ "ConnectionStrings": { "SQLConnection": "server=127.0.0.1;database=eftest;userid=root;pwd=123456;port=3306;sslmode=none;" }, "server.urls": "http://localhost:5001" //監聽端口配置,可多個 }
打開PM選擇默認項目Entityjson
輸入api
PM> Add-Migration init
若提示The configuration file 'appsettings.json' was not found and is not optional. The physical path is 'E:\VS項目\EFTest\Entity\bin\Debug\netcoreapp2.0\appsettings.json'.微信
則爲沒檢測到appsettings.json,須要文件更改屬性爲複製app
提示後進行更新數據庫,以下爲更新成功。
PM> update-database
最後Entity項目內容以下
新建.NetCore類庫項目Repository並引用項目Entity
PM> Install-Package Microsoft.EntityFrameworkCore -version 2.0.3
PM> Install-Package LinqKit.Microsoft.EntityFrameworkCore -version 1.1.15
using System; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Collections.Generic; namespace Repository { internal static class LinqExtensions { private static PropertyInfo GetPropertyInfo(Type objType, string name) { var properties = objType.GetProperties(); var matchedProperty = properties.FirstOrDefault(p => p.Name == name); if (matchedProperty == null) { throw new ArgumentException("name"); } return matchedProperty; } private static LambdaExpression GetOrderExpression(Type objType, PropertyInfo pi) { var paramExpr = Expression.Parameter(objType); var propAccess = Expression.PropertyOrField(paramExpr, pi.Name); var expr = Expression.Lambda(propAccess, paramExpr); return expr; } /// <summary> /// 多個OrderBy用逗號隔開,屬性前面帶-號表示反序排序,exp:"name,-createtime" /// </summary> /// <typeparam name="T"></typeparam> /// <param name="query"></param> /// <param name="name"></param> /// <returns></returns> public static IEnumerable<T> OrderByBatch<T>(this IEnumerable<T> query, string name) { var index = 0; var a = name.Split(','); foreach (var item in a) { var m = index++ > 0 ? "ThenBy" : "OrderBy"; if (item.StartsWith("-")) { m += "Descending"; name = item.Substring(1); } else { name = item; } name = name.Trim(); var propInfo = GetPropertyInfo(typeof(T), name); var expr = GetOrderExpression(typeof(T), propInfo); var method = typeof(Enumerable).GetMethods().FirstOrDefault(mt => mt.Name == m && mt.GetParameters().Length == 2); var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType); query = (IEnumerable<T>)genericMethod.Invoke(null, new object[] { query, expr.Compile() }); } return query; } /// <summary> /// 多個OrderBy用逗號隔開,屬性前面帶-號表示反序排序,exp:"name,-createtime" /// </summary> /// <typeparam name="T"></typeparam> /// <param name="query"></param> /// <param name="name"></param> /// <returns></returns> public static IQueryable<T> OrderByBatch<T>(this IQueryable<T> query, string name) { var index = 0; var a = name.Split(','); foreach (var item in a) { var m = index++ > 0 ? "ThenBy" : "OrderBy"; if (item.StartsWith("-")) { m += "Descending"; name = item.Substring(1); } else { name = item; } name = name.Trim(); var propInfo = GetPropertyInfo(typeof(T), name); var expr = GetOrderExpression(typeof(T), propInfo); var method = typeof(Queryable).GetMethods().FirstOrDefault(mt => mt.Name == m && mt.GetParameters().Length == 2); var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType); query = (IQueryable<T>)genericMethod.Invoke(null, new object[] { query, expr }); } return query; } /// <summary> /// 正序排序單個 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="query"></param> /// <param name="name"></param> /// <returns></returns> public static IQueryable<T> OrderBy<T>(this IQueryable<T> query, string name) { var propInfo = GetPropertyInfo(typeof(T), name); var expr = GetOrderExpression(typeof(T), propInfo); var method = typeof(Queryable).GetMethods().FirstOrDefault(m => m.Name == "OrderBy" && m.GetParameters().Length == 2); var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType); return (IQueryable<T>)genericMethod.Invoke(null, new object[] { query, expr }); } /// <summary> /// 正序排序單個(非首個) /// </summary> /// <typeparam name="T"></typeparam> /// <param name="query"></param> /// <param name="name"></param> /// <returns></returns> public static IQueryable<T> ThenBy<T>(this IQueryable<T> query, string name) { var propInfo = GetPropertyInfo(typeof(T), name); var expr = GetOrderExpression(typeof(T), propInfo); var method = typeof(Queryable).GetMethods().FirstOrDefault(m => m.Name == "ThenBy" && m.GetParameters().Length == 2); var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType); return (IQueryable<T>)genericMethod.Invoke(null, new object[] { query, expr }); } /// <summary> /// 反序排序單個 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="query"></param> /// <param name="name"></param> /// <returns></returns> public static IQueryable<T> OrderByDescending<T>(this IQueryable<T> query, string name) { var propInfo = GetPropertyInfo(typeof(T), name); var expr = GetOrderExpression(typeof(T), propInfo); var metMethods = typeof(Queryable).GetMethods(); var method = metMethods.FirstOrDefault(m => m.Name == "OrderByDescending" && m.GetParameters().Length == 2); var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType); return (IQueryable<T>)genericMethod.Invoke(null, new object[] { query, expr }); } /// <summary> /// 反序排序單個(非首個) /// </summary> /// <typeparam name="T"></typeparam> /// <param name="query"></param> /// <param name="name"></param> /// <returns></returns> public static IQueryable<T> ThenByDescending<T>(this IQueryable<T> query, string name) { var propInfo = GetPropertyInfo(typeof(T), name); var expr = GetOrderExpression(typeof(T), propInfo); var metMethods = typeof(Queryable).GetMethods(); var method = metMethods.FirstOrDefault(m => m.Name == "ThenByDescending" && m.GetParameters().Length == 2); var genericMethod = method.MakeGenericMethod(typeof(T), propInfo.PropertyType); return (IQueryable<T>)genericMethod.Invoke(null, new object[] { query, expr }); } } }
以及分頁支持類PageData<T>
using System; using System.Collections.Generic; using System.Text; namespace Repository { public class PageData<T> { public List<T> Rows { get; set; } public long Totals { get; set; } } }
using Entity; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore.Infrastructure; using System.IO; using Entity.Table; namespace Repository { public class RepositoryBase<T> where T : EntityBase { private readonly DbSet<T> _dbSet; public AeDbContext DbContext { get; } = null; public RepositoryBase(AeDbContext context) { DbContext = context; _dbSet = DbContext.Set<T>(); } public DatabaseFacade Database => DbContext.Database; public IQueryable<T> Entities => _dbSet.AsQueryable().AsNoTracking(); public int SaveChanges() { return DbContext.SaveChanges(); } public async Task<int> SaveChangesAsync() { return await DbContext.SaveChangesAsync(); } public bool Any(Expression<Func<T, bool>> whereLambd) { return _dbSet.Where(whereLambd).Any(); } public void Disposed() { throw new Exception("不容許在這裏釋放上下文,請在UnitOfWork中操做"); //DbContext.Dispose(); } #region 插入數據 public bool Insert(T entity, bool isSaveChange = true) { _dbSet.Add(entity); if (isSaveChange) { return SaveChanges() > 0; } return false; } public async Task<bool> InsertAsync(T entity, bool isSaveChange = true) { _dbSet.Add(entity); if (isSaveChange) { return await SaveChangesAsync() > 0; } return false; } public bool Insert(List<T> entitys, bool isSaveChange = true) { _dbSet.AddRange(entitys); if (isSaveChange) { return SaveChanges() > 0; } return false; } public async Task<bool> InsertAsync(List<T> entitys, bool isSaveChange = true) { _dbSet.AddRange(entitys); if (isSaveChange) { return await SaveChangesAsync() > 0; } return false; } #endregion #region 刪除 public bool Delete(T entity, bool isSaveChange = true) { _dbSet.Attach(entity); _dbSet.Remove(entity); return isSaveChange ? SaveChanges() > 0 : false; } public bool Delete(List<T> entitys, bool isSaveChange = true) { entitys.ForEach(entity => { _dbSet.Attach(entity); _dbSet.Remove(entity); }); return isSaveChange ? SaveChanges() > 0 : false; } public virtual async Task<bool> DeleteAsync(T entity, bool isSaveChange = true) { _dbSet.Attach(entity); _dbSet.Remove(entity); return isSaveChange ? await SaveChangesAsync() > 0 : false; } public virtual async Task<bool> DeleteAsync(List<T> entitys, bool isSaveChange = true) { entitys.ForEach(entity => { _dbSet.Attach(entity); _dbSet.Remove(entity); }); return isSaveChange ? await SaveChangesAsync() > 0 : false; } #endregion #region 更新數據 public bool Update(T entity, bool isSaveChange = true, List<string> updatePropertyList = null, bool modified = true) { if (entity == null) { return false; } _dbSet.Attach(entity); var entry = DbContext.Entry(entity); if (updatePropertyList == null) { entry.State = EntityState.Modified;//全字段更新 } else { if (modified) { updatePropertyList.ForEach(c => { entry.Property(c).IsModified = true; //部分字段更新的寫法 }); } else { entry.State = EntityState.Modified;//全字段更新 updatePropertyList.ForEach(c => { entry.Property(c).IsModified = false; //部分字段不更新的寫法 }); } } if (isSaveChange) { return SaveChanges() > 0; } return false; } public bool Update(List<T> entitys, bool isSaveChange = true) { if (entitys == null || entitys.Count == 0) { return false; } entitys.ForEach(c => { Update(c, false); }); if (isSaveChange) { return SaveChanges() > 0; } return false; } public async Task<bool> UpdateAsync(T entity, bool isSaveChange = true, List<string> updatePropertyList = null, bool modified = true) { if (entity == null) { return false; } _dbSet.Attach(entity); var entry = DbContext.Entry<T>(entity); if (updatePropertyList == null) { entry.State = EntityState.Modified;//全字段更新 } else { if (modified) { updatePropertyList.ForEach(c => { entry.Property(c).IsModified = true; //部分字段更新的寫法 }); } else { entry.State = EntityState.Modified;//全字段更新 updatePropertyList.ForEach(c => { entry.Property(c).IsModified = false; //部分字段不更新的寫法 }); } } if (isSaveChange) { return await SaveChangesAsync() > 0; } return false; } public async Task<bool> UpdateAsync(List<T> entitys, bool isSaveChange = true) { if (entitys == null || entitys.Count == 0) { return false; } entitys.ForEach(c => { _dbSet.Attach(c); DbContext.Entry<T>(c).State = EntityState.Modified; }); if (isSaveChange) { return await SaveChangesAsync() > 0; } return false; } #endregion #region 查找 public long Count(Expression<Func<T, bool>> predicate = null) { if (predicate == null) { predicate = c => true; } return _dbSet.LongCount(predicate); } public async Task<long> CountAsync(Expression<Func<T, bool>> predicate = null) { if (predicate == null) { predicate = c => true; } return await _dbSet.LongCountAsync(predicate); } public T Get(object id) { if (id == null) { return default(T); } return _dbSet.Find(id); } public T Get(Expression<Func<T, bool>> predicate = null, bool isNoTracking = true) { var data = isNoTracking ? _dbSet.Where(predicate).AsNoTracking() : _dbSet.Where(predicate); return data.FirstOrDefault(); } public async Task<T> GetAsync(object id) { if (id == null) { return default(T); } return await _dbSet.FindAsync(id); } public async Task<T> GetAsync(Expression<Func<T, bool>> predicate = null, bool isNoTracking = true) { var data = isNoTracking ? _dbSet.Where(predicate).AsNoTracking() : _dbSet.Where(predicate); return await data.FirstOrDefaultAsync(); } public async Task<List<T>> GetListAsync(Expression<Func<T, 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<T> GetList(Expression<Func<T, 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<T>> LoadAsync(Expression<Func<T, 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<T> Load(Expression<Func<T, bool>> predicate = null, bool isNoTracking = true) { if (predicate == null) { predicate = c => true; } return isNoTracking ? _dbSet.Where(predicate).AsNoTracking() : _dbSet.Where(predicate); } #region 分頁查找 /// <summary> /// 分頁查詢異步 /// </summary> /// <param name="whereLambda">查詢添加(可有,可無)</param> /// <param name="ordering">排序條件(必定要有)</param> /// <param name="pageIndex">當前頁碼</param> /// <param name="pageSize">每頁大小</param> /// <param name="isOrder">排序正反</param> /// <returns></returns> public async Task<PageData<T>> GetPageAsync<TKey>(Expression<Func<T, bool>> whereLambda, Expression<Func<T, TKey>> orderBy, int pageIndex, int pageSize, bool isOrder = true, bool isNoTracking = true) { IQueryable<T> data = isOrder ? _dbSet.OrderBy(orderBy) : _dbSet.OrderByDescending(orderBy); if (whereLambda != null) { data = isNoTracking ? data.Where(whereLambda).AsNoTracking() : data.Where(whereLambda); } PageData<T> pageData = new PageData<T> { Totals = await data.CountAsync(), Rows = await data.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync() }; return pageData; } /// <summary> /// 分頁查詢異步 /// </summary> /// <param name="whereLambda">查詢添加(可有,可無)</param> /// <param name="ordering">排序條件(必定要有,多個用逗號隔開,倒序開頭用-號)</param> /// <param name="pageIndex">當前頁碼</param> /// <param name="pageSize">每頁大小</param> /// <returns></returns> public async Task<PageData<T>> GetPageAsync(Expression<Func<T, bool>> whereLambda, string ordering, int pageIndex, int pageSize, bool isNoTracking = true) { // 分頁 必定注意: Skip 以前必定要 OrderBy if (string.IsNullOrEmpty(ordering)) { ordering = nameof(T) + "Id";//默認以Id排序 } var data = _dbSet.OrderByBatch(ordering); if (whereLambda != null) { data = isNoTracking ? data.Where(whereLambda).AsNoTracking() : data.Where(whereLambda); } //查看生成的sql,找到大數據下分頁巨慢緣由爲order by 耗時 //var sql = data.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToSql(); //File.WriteAllText(@"D:\sql.txt",sql); PageData<T> pageData = new PageData<T> { Totals = await data.CountAsync(), Rows = await data.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync() }; return pageData; } /// <summary> /// 分頁查詢 /// </summary> /// <param name="whereLambda">查詢添加(可有,可無)</param> /// <param name="ordering">排序條件(必定要有,多個用逗號隔開,倒序開頭用-號)</param> /// <param name="pageIndex">當前頁碼</param> /// <param name="pageSize">每頁大小</param> /// <returns></returns> public PageData<T> GetPage(Expression<Func<T, bool>> whereLambda, string ordering, int pageIndex, int pageSize, bool isNoTracking = true) { // 分頁 必定注意: Skip 以前必定要 OrderBy if (string.IsNullOrEmpty(ordering)) { ordering = nameof(T) + "Id";//默認以Id排序 } var data = _dbSet.OrderByBatch(ordering); if (whereLambda != null) { data = isNoTracking ? data.Where(whereLambda).AsNoTracking() : data.Where(whereLambda); } PageData<T> pageData = new PageData<T> { Totals = data.Count(), Rows = data.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList() }; return pageData; } #endregion #endregion } }
using Entity; using Entity.Table; using System; using System.Collections.Generic; using System.Text; namespace Repository.Table { public class SysUserRepository : RepositoryBase<SysUser> { public SysUserRepository(AeDbContext context) : base(context) { } } }
using Entity; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Storage; using Repository.Table; using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Repository { public class UnitOfWork : IDisposable { public static UnitOfWork Instance = new UnitOfWork(new AeDbContext()); public AeDbContext DbContext { get; set; } = null; public UnitOfWork(AeDbContext dbContext) { DbContext = dbContext; } #region 字段 private SysUserRepository _SysUserRepository = null; #endregion #region 操做類屬性 public SysUserRepository SysUserRepository => _SysUserRepository ?? (_SysUserRepository = new SysUserRepository(DbContext)); #endregion #region 倉儲操做(提交事務保存SaveChanges(),回滾RollBackChanges(),釋放資源Dispose()) /// <summary> /// 保存 /// </summary> public int SaveChanges() { return DbContext.SaveChanges(); } public async Task<int> SaveChangesAsync() { return await DbContext.SaveChangesAsync(); } /// <summary> /// 回滾 /// </summary> public void RollBackChanges() { var items = DbContext.ChangeTracker.Entries().ToList(); items.ForEach(o => o.State = EntityState.Unchanged); } /// <summary> /// 釋放資源 /// </summary> private bool disposed = false; protected virtual void Dispose(bool disposing) { if (!this.disposed) { if (disposing) { DbContext.Dispose();//隨着工做單元的銷燬而銷燬 } } this.disposed = true; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } public IDbContextTransaction BeginTransaction() { var scope = DbContext.Database.BeginTransaction(); return scope; } #endregion } }
這樣倉儲層就構造完成了,篇幅已經很長了,Service層就先不介紹了。
新建.NetCore的項目的Web應用程序ApiTest,選擇webapi方式,並引用Entity和Repository項目
public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddDbContext<AeDbContext>(options => options.UseMySql(Configuration.GetConnectionString("SQLConnection")));
services.AddTransient(typeof(UnitOfWork));//注入工做單元 }
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Repository; namespace ApiTest.Controllers { [Route("api/[controller]")] public class ValuesController : Controller { UnitOfWork _unitOfWork; public ValuesController(UnitOfWork unitOfWork) { _unitOfWork = unitOfWork; } // GET api/values [HttpGet] public IEnumerable<string> Get() { var adminModel = _unitOfWork.SysUserRepository.Get("admin"); if(adminModel == null) { adminModel = new Entity.Table.SysUser() { SysUserId = "admin", UserName = "admin", Password = "123456", UserType = "1", CreateTime = DateTime.Now, Status = 1, Sort = 0 }; _unitOfWork.SysUserRepository.Insert(adminModel); } return new List<string> { adminModel.UserName , adminModel.Password }; } // GET api/values/5 [HttpGet("{id}")] public string Get(int id) { return "value"; } // POST api/values [HttpPost] public void Post([FromBody]string value) { } // PUT api/values/5 [HttpPut("{id}")] public void Put(int id, [FromBody]string value) { } // DELETE api/values/5 [HttpDelete("{id}")] public void Delete(int id) { } } }
測試結果:
倉儲分頁查詢 測試
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Entity.Table; using LinqKit; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Repository; namespace ApiTest.Controllers { [Produces("application/json")] [Route("api/[controller]")] public class QueryPageController : Controller { UnitOfWork _unitOfWork; public QueryPageController(UnitOfWork unitOfWork) { _unitOfWork = unitOfWork; } /// <summary> /// 分頁測試 /// </summary> /// <returns></returns> [HttpGet] public async Task<IActionResult> Get(string userName,int? Status,string NikeName) { var userCount = _unitOfWork.SysUserRepository.Count(); if(userCount < 100) { await CreateUser(100); } //獲取分頁數據方式1 //獲取用戶名包含user的排序根據Sort正序,CreateTime倒序排序的第1頁的20條數據 var pageModel = await _unitOfWork.SysUserRepository.GetPageAsync(o => o.UserName.Contains("user") && o.Status == 1, "Sort,-CreateTime", 1, 20); //獲取分頁數據方式2 //使用PredicateBuilder獲取分頁數據方式支持篩選 var predicate = PredicateBuilder.New<SysUser>(true);//查詢條件,推薦後臺使用這種方式靈活篩選 #region 添加條件查詢 if (!string.IsNullOrEmpty(userName)) { predicate = predicate.And(i => i.UserName.Contains(userName)); } if (Status != null) { predicate = predicate.And(i => i.Status.Equals(Status)); } if (!string.IsNullOrEmpty(NikeName)) { predicate = predicate.And(i => i.NikeName.Equals(NikeName)); } #endregion var pageModel1 = await _unitOfWork.SysUserRepository.GetPageAsync(predicate, "Sort,-CreateTime", 1, 20); return Json(new { pageModel, pageModel1 }); } /// <summary> /// 構造數據 /// </summary> /// <param name="count"></param> /// <returns></returns> public async Task<bool> CreateUser(int count = 1) { List<SysUser> inserUsers = new List<SysUser>(); for (int i = 0; i < count; i++) { inserUsers.Add(new SysUser { SysUserId = Guid.NewGuid().ToString("N"), UserName = $"user{i}", Password = "123456", UserType = "0", CreateTime = DateTime.Now, Status = 1, Sort = 0 }); } return await _unitOfWork.SysUserRepository.InsertAsync(inserUsers); } } }
結果:
最後附上github源碼:https://github.com/atorzhang/EFTest
注:原創,轉載請註明出處,原文地址:http://www.javashuo.com/article/p-xomoniwe-m.html