tnblog
首页
视频
资源
登录

EF扩展反射实现动态排序+表达式树

5682人阅读 2019/10/23 17:29 总访问:126104 评论:0 收藏:1 手机
分类: .NET MVC

现在各种网站上的表格可以通过点击排头来实现排序

例如:


今天我就来一探究竟,这是怎么实现的呢?



具体步骤:

    我通过写扩展方法的方式来实现的,扩展EF。当然我们得写一个灵活性强的,支持多种类型的,通过反射来实行中转,我们反射调用方法的时候可以动态传递类型。


定义一个静态方法,参数:sort(排序的字段),sortway(排序方式)

  1. public static IQueryable<TSource> MyOrderBy<TSource>(this IQueryable<TSource> source, string sort, string sortway)
  2. {
  3.         
  4. }


1、获取排序字段的类型

  1. //首先要拿到排序字段的类型
  2. Type type = typeof(TSource).GetProperty(sort).PropertyType;


2、把处理升序和降序、生成Lamdba表达式的方法提出来写

    

  1.         /// <summary>
  2.         /// 处理升序的方法
  3.         /// </summary>
  4.         public static IQueryable<TSource> DealAsc<TSource, M>(this IQueryable<TSource> source, string sort)
  5.         {
  6.             //生成lamdba表达式
  7.             Expression<Func<TSource, M>> lamdba = CreateLamdba<TSource, M>(source, sort);
  8.             source = source.OrderBy(lamdba);
  9.             return source;
  10.         }
  11.         /// <summary>
  12.         /// 处理降序的方法
  13.         /// </summary>
  14.         public static IQueryable<TSource> DealDesc<TSource, M>(this IQueryable<TSource> source, string sort)
  15.         {
  16.             //生成lamdba表达式
  17.             Expression<Func<TSource, M>> lamdba = CreateLamdba<TSource, M>(source, sort);
  18.             source = source.OrderByDescending(lamdba);
  19.             return source;
  20.         }
  21.         /// <summary>
  22.         /// 生成Lamdba表达式
  23.         /// </summary>
  24.         static Expression<Func<TSource, M>> CreateLamdba<TSource, M>(this IQueryable<TSource> source, string sort)
  25.         {
  26.             var parame = Expression.Parameter(typeof(TSource), "a");
  27.             var body = Expression.Property(parame, sort);
  28.             //生成lamdba表达式
  29.             Expression<Func<TSource, M>> lamdba = Expression.Lambda<Func<TSource, M>>(body, parame);
  30.             return lamdba;
  31.         }

3、通过反射来调用方法,因为这样可以动态传递类型,如果直接调用不能动态传递类型,只能指定类型

    1)先通过反射拿到方法,并且判断排序方式调用对应的方法

  1.     var mothed = typeof(MyTools).GetMethod(sortway=="asc""DealAsc":"DealDesc");

    2)最关键的一步,给方法指定类型

  1.       mothed = mothed.MakeGenericMethod(typeof(TSource), type);

    3)调用方法

  1.         IQueryable<TSource> result = (IQueryable<TSource>)mothed.Invoke(nullnew object[] { source, sort });


下面奉上完整代码:

  1. public static class MyTools
  2.     {
  3.         public static IQueryable<TSource> MyOrderBy<TSource>(this IQueryable<TSource> source, string sort, string sortway)
  4.         {
  5.             if (!string.IsNullOrEmpty(sort))
  6.             {
  7.                 //首先要拿到排序字段的类型
  8.                 Type type = typeof(TSource).GetProperty(sort).PropertyType;
  9.                 //如果直接调用处理升序或者降序的方法,参数类型还是无法传递过来
  10.                 //例如:DealAsc(TSource,type);
  11.                 //虽然type取到的是参数类型,但是type作为变量,不能直接传递过去
  12.                 //所以,我们可以用反射调用方法来实现,这样可以动态传递参数类型
  13.                 //1、先用反射拿到方法
  14.                 var mothed = typeof(MyTools).GetMethod(sortway=="asc""DealAsc":"DealDesc");
  15.                 //2、给方法传递类型
  16.                 mothed = mothed.MakeGenericMethod(typeof(TSource), type);
  17.                 //3、调用方法
  18.                 IQueryable<TSource> result = (IQueryable<TSource>)mothed.Invoke(nullnew object[] { source, sort });
  19.                 return result;
  20.             }
  21.             return source;
  22.         }
  23.         /// <summary>
  24.         /// 处理升序的方法
  25.         /// </summary>
  26.         public static IQueryable<TSource> DealAsc<TSource, M>(this IQueryable<TSource> source, string sort)
  27.         {
  28.             //生成lamdba表达式
  29.             Expression<Func<TSource, M>> lamdba = CreateLamdba<TSource, M>(source, sort);
  30.             source = source.OrderBy(lamdba);
  31.             return source;
  32.         }
  33.         /// <summary>
  34.         /// 处理降序的方法
  35.         /// </summary>
  36.         public static IQueryable<TSource> DealDesc<TSource, M>(this IQueryable<TSource> source, string sort)
  37.         {
  38.             //生成lamdba表达式
  39.             Expression<Func<TSource, M>> lamdba = CreateLamdba<TSource, M>(source, sort);
  40.             source = source.OrderByDescending(lamdba);
  41.             return source;
  42.         }
  43.         /// <summary>
  44.         /// 生成Lamdba表达式
  45.         /// </summary>
  46.         static Expression<Func<TSource, M>> CreateLamdba<TSource, M>(this IQueryable<TSource> source, string sort)
  47.         {
  48.             var parame = Expression.Parameter(typeof(TSource), "a");
  49.             var body = Expression.Property(parame, sort);
  50.             //生成lamdba表达式
  51.             Expression<Func<TSource, M>> lamdba = Expression.Lambda<Func<TSource, M>>(body, parame);
  52.             return lamdba;
  53.         }
  54.     }


调用就很简单了,直接点出来就行


学了这一招,妈妈再也不用担心我的类型传不了了!

评价

NET Core 使用 EF Code First

下面这些内容很老了看这篇:https://www.tnblog.net/aojiancc2/article/details/5365 项目使用多层,把数据库访问...

C out、rEF关键字的用法和区别

说说自己对out、ref的认识,面试问到的几率很高哟。out:classProgram { /* *out、ref都是引用传递,传递后使用都会改变...

Net Core使用EF之DB First

一.新建一个.net core的MVC项目新建好项目后,不能像以前一样直接在新建项中添加ef了,需要用命令在添加ef的依赖二.使用Nug...

EF6动态添加条件

例如我们要匹配一个集合中的所有关键字,我们首先想到的做法是这样的publicList&lt;Article&gt;GetArtByKeys(List&lt;strin...

Net Core使用依赖注入来装载EF的上下文对象

妹子情人节快乐~.net core中用了不少的依赖注入,官方文档中也推荐使用。这样使用依赖注入来管理ef对象,还是比较科学,比如...

NET CORE配置EF连接字符串。windows验证的连接字符串配置

在appsettings.json中配置好连接字符串{&quot;ConnectionStrings&quot;:{ &quot;BloggingDatabase&quot;:&quot;Server=(lo...

使用REFit框架访问REST接口

改装是一个类型安全的REST开源库,是一套基于RESTful架构的.NET客户端实现,内部使用HttpClient类封装,可通过改装更加简单...

docker启动报错 No dEFault Boot2Docker ISO found locally downloading the latest

这是因为,启动时如果检测到没有 Boot2Docker,就会去下载,这个下载过程出现网络连接上的错误了,导致启动失败。可以去下...

扩展EF自动映射需要查询的字段(表达式树Expression),动态构建返回值

Entity Framework 动态构造select表达式比如我们需要返回某些字段会采用如下的写法但是发现每次都去写select如果字段很多不...

layer弹窗+EF引入独立页面进行操作

使用layer弹窗进行操作的时候我们可以使用type=2,来把一个独立的页面指向content内容例如我们有一个表格,点击添加后,我...

Entity Framework常用查询,EF joinEF多表联查,原生sql。EF 多表查询。AsNoTracking

直接执行sql语句//全表查询 List&lt;Users&gt;ulist=se.Database.SqlQuery&lt;Users&gt;(&quot;select*fromusers&quot;).T...

EF Code First常用命令

Enable-Migrations启用数据库迁移Enable-Migrations –EnableAutomaticMigrations 启动自动迁移Add-Migration Name(名字可...

EF Code First 多对多关系配置

Code First配置多对多关系,常规有两种方法例如我们有一张学生表,和一张课程表,学生和课程是一个多对多的关系方法1:单纯...

解决:基础提供程序在 Open 上失败,EF无法生成实体问题

在学校图书馆的电脑上安装VS2013和SQL R2后,调试项目报错:基础提供程序在 Open 上失败怀疑是数据库的问题,然后删除数据...

net core过滤器。net core过滤器中获取依赖注入对象。net core过滤器中使用依赖注入。ServicEFilter 

虽然对象都可以直接实例化得到。但是所有的对象依赖关系,都用DI容器去管理,这样后面想要更换对象的时候也非常方便,项目...

EF状态System.Data.EntityState的一点理解

System.Data.EntityState一共有五种状态分别是Added,Deleted,Modified,UnChanged,Detached下面给一个简单的解释System.Data...
网络上你重拳出击,现实中你刚上初一
排名
27
文章
20
粉丝
11
评论
5
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术
早点脱单吧,我怕你孤独终老,却又长命百岁。