• Entity Framework分页扩展


    Entity Framework分页在我初入门时总是困扰这我,无论是SQL分页还是Entity Framework的分页,总是显得那么麻烦,因此对于Entity Framework单独封装了分页。


    一、分页原理

      对于分页本质是针对现有数据进行分段展示,如图:

      对于这12条数据属于筛选后的数据,针对筛选后的数据我们再进行分页,PageSize(每页数量),最后一页数量>0 && <PageSize则算一页。

    二、分页设计(对于设计并不是很专业,马马虎虎) 

      

      最终我们通过PageListBase作为实现类,在通过扩展方法ExtensionIQueryable这个一个扩展类,针对IQueryable<T>进行扩展。

      

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Diagnostics;
     4 using System.IO;
     5 using System.Linq;
     6 using System.Linq.Expressions;
     7 using System.Runtime.Serialization;
     8 using System.Runtime.Serialization.Formatters.Binary;
     9 using System.Text;
    10 using System.Threading.Tasks;
    11 
    12 namespace Sunc.Framework.Repository.Entity.Extension
    13 {
    14     public static class ExtensionIQueryable
    15     {
    16         /// <summary>
    17         /// 分页
    18         /// </summary>
    19         /// <param name="list"> 数据源 </param>
    20         /// <param name="order"> 排序表达式 </param>
    21         /// <param name="pageIndex"> 第几页 </param>
    22         /// <param name="pageSize"> 每页记录数 </param>
    23         /// <param name="count"> 记录总数 </param>
    24         /// <returns></returns>
    25         public static IQueryable<T> Pagination<T, TKey>(this IQueryable<T> list, Expression<Func<T, bool>> predicate, Expression<Func<T, TKey>> order, int pageIndex, int pageSize, out int count, bool isOrder = true)
    26         {
    27             try
    28             {
    29                 var source = list.Where(predicate.Compile()).AsQueryable();
    30                 count = source.Count();
    31                 if (isOrder)
    32                     return source.OrderBy(order).Skip((pageIndex - 1) * pageSize).Take(pageSize);
    33                 return source.OrderByDescending(order).Skip((pageIndex - 1) * pageSize).Take(pageSize);
    34             }
    35             catch (Exception ex)
    36             {
    37                 Console.WriteLine(ex.Message);
    38                 Debug.WriteLine(ex.Message);
    39                 count = 0;
    40                 return new List<T>().AsQueryable();
    41             }
    42         }
    43 
    44         public static V ToModel<T, V>(this T t) where T : ModelBase, V where V : ModelBase
    45         {
    46             return t;
    47         }
    48         public static string ToJson(this IQueryable<DatabaseModel> models)
    49         {
    50             return EntityBase.ToJson(models);
    51         }
    52 
    53     }
    54 }

     三、最终实现

      1、我们使用Entity Framework应该知道懒加载

         public virtual DbSet<T_WindFarm> T_WindFarm { set; get; }

       我们在进行EF一系列表达式操作查询,数据实际并未查询,只用我们真正使用的时候才会执行查询。

      2、EF查询

        ItsmContext 扩展自 DbContext,多线程操作会存在诸多问题,因此我们采用单例模式

        

     1    private static object _asynContextLock = new object();
     2         private static ItsmContext _context;
     3         public static ItsmContext Context
     4         {
     5             get
     6             {
     7                 lock (_asynContextLock)
     8                 {
     9                     if (_context == null)
    10                     {
    11                         _context = new ItsmContext();
    12                     }
    13                     return _context;
    14                 }
    15             }
    16         }

      3、实现类继承IBaseMethodPageList<Entity>

        

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Linq.Expressions;
     5 using System.Text;
     6 using System.Threading.Tasks;
     7 using Sunc.Framework.Repository.Entity;
     8 
     9 namespace Sunc.Framework.Repository.Interface.BaseMethod
    10 {
    11     public interface IBaseMethodPageList<Entity>
    12     {
    13         IBaseEntityPageList<Entity> GetPageList(int pageIndex, int pageSize);
    14 
    15 
    16         IBaseEntityPageList<Entity> GetPageList<TKey>(Expression<Func<Entity, bool>> predicate, Expression<Func<Entity, TKey>> order, int pageIndex, int pageSize, bool isOrder = true);
    17     }
    18 }

      实现类中实现方法

      

      a、using Sunc.Framework.Repository.Entity.Extension;是针对ExtensionIQueryable的引用;

      b、ItsmContext.Context.T_WindFarm.Pagination(predicate, order, pageIndex, pageSize, out count, true);我们通过筛选条件获取PageIndex即为当前页面IQueryable<T>实际结果集;

      c、 var pageList = new PageListBase<T_WindFarm>(models,pageIndex,pageSize,count);我们不用在关心如何去分页,只需要把结果集和总数传入即可;

      d、返回值为IBaseEntityPageList<T_WindFarm> 我们知道它继承于IBasePageList以及它的属性都为只读属性,因此我们可以防止数据被篡改

    4、最终结果

    这样一来,我们不用考虑太多的分页问题

      A、ExtensionIQueryable -> Pagination方法帮助我们完成数据筛选得到实际的数据总数并将实际当前页数据、总数返回;

      B、PageListBase<T> 可以通过构造函数或者AddRange方法将当前页数据集加载,通过传入的count计算出实际页数。

    具体的源码

    Github:Sunc.Framework.Repository
    IBasePageList Sunc.Framework.Repository.Interface
    IBaseEntityPageList<Entity>  Sunc.Framework.Repository.Interface.BaseMethod
    PageListBase<Entity> Sunc.Framework.Repository.Entity
    ExtensionIQueryable Sunc.Framework.Repository.Entity.Extension
    IBaseMethodPageList<Entity> Sunc.Framework.Repository.Interface.BaseMethod

     --分享源于热爱

    Sunc

  • 相关阅读:
    使用 Responsive Elements 快速构建响应式网站
    分享25个新鲜出炉的 Photoshop 高级教程
    【特别推荐】Node.js 入门教程和学习资源汇总
    高清精美壁纸:2013年11月桌面日历壁纸免费下载
    Allocation-Free Collections(在堆栈上使用内存)
    李愬雪夜袭蔡州:挽救唐朝国祚的关键之战(先示弱于敌军,对降将攻心为上、以诚待人,然后逐步收集情报,最后出奇兵奇袭。但出奇兵也要有预案,否则会被两面夹击。做一件事情真不容易)
    C 与 C++ 谁的效率高,为什么?(结论是,两个不同层次的语言不应该相互比较,非要比较的话,是不同情况下各有快慢)
    在Win10上,Android Studio检测不到设备的解决方案
    web系统整体优化
    服务器间通讯问题的排查
  • 原文地址:https://www.cnblogs.com/umeall/p/9006731.html
Copyright © 2020-2023  润新知