最近在写ORM框架,其中遇到一个难点,就是作为框架调用方如何将查询条件传入框架内。其中就用到了Expression。


Func委托

要Expression先要了解Func委托,Func委托的样式是:

Func<T,TResult>

他是一种C#提供的固定的委托方法,算是微软提供的一种语法糖。

举例说明:

1 //声明
2 Func<int, int> func = f => f + 1;
3 //调用
4 int funcResult=func(1);
5
6 //结果=2

其中,Func<int, int>中第一个int是参数类型,第二个int是返回值类型。

Func<int, int> func = f => f + 1;等号后跟表达式中的参数,=>是lambda表达式的运算符,后跟方法体。

与下面这种正常的委托写法是一样的效果:

声明委托类型:

delegate int Function(int f);

赋值委托方法:

int ffunc(int f)
{
return f + 1;
}
//声明委托对象
Function function;
//赋值对象
function = ffunc;
int ffuncResult = function(1);

其中我们可以看出来,不管是上面Func的写法还是delegate写法,都是相当于把方法作为参数进行传递。

注意Func只能传递一个参数,但是可以自定义对象作为参数类型变相的传递多个参数。


Expression表达式树

理解了委托和上面的Func委托Expression就很容易理解了。

先看Expression的官方文档是怎么说的:

~~好吧,官方文档实在看不懂,那F12一下:

这里就能看出来了一部分内容,Expression是要使用委托类型的,而且只能是lambda表达式类型的委托,所以最好就是Func委托,这也是为什么刚开始我要讲Func委托的原因。

他的使用形式上是这样的:

Expression<Func<T,TResult>>

可以看出他是在委托上又嵌套了一层,就像树一样,“委托树”,因为只能嵌套lambda表达式,所以官方叫法是表达式树。

那要怎么用呢?此处列举一种用法,就是我开头提到的获取对象的属性名称。

声明实体:

public class Class2
{
public string A1 { get; set; }
public int? A2 { get; set; }
}

获取属性名称方法:

//获取属性名称
string ConvertOrderBy<TEntity>(Expression<Func<TEntity, object>> orderby) where TEntity : class
{
var member = orderby.Body as MemberExpression;
var unary = orderby.Body as UnaryExpression;
return member != null ? member.Member.Name : (unary != null ? (unary.Operand as MemberExpression).Member.Name : null);
}
string SetOrderBy<TEntity>(Expression<Func<TEntity,object>> orderBy) where TEntity : class
{
return ConvertOrderBy(orderBy);
}
var linqStr = SetOrderBy<Class2>(s => s.A2);

运行结果:


总结

Expression在EF框架中存在大量使用,主要是需要框架底层需要知道传入属性的名称和类型。在使用时一定要注意Expression中一定只能是lambda表达式类型的委托。

Func委托与表达式树Expression的更多相关文章

  1. jQuery find() 搜索所有段落中的后代 C# find() 第一个匹配元素 Func 有返回值 Action是没有返回值 Predicate 只有一个参数且返回值为bool 表达式树Expression

    所有p后代span Id为 TotalProject 的 select 标签 的后代 option标签 为选中的 text using System; using System.Collections ...

  2. [C#] C# 知识回顾 - 表达式树 Expression Trees

    C# 知识回顾 - 表达式树 Expression Trees 目录 简介 Lambda 表达式创建表达式树 API 创建表达式树 解析表达式树 表达式树的永久性 编译表达式树 执行表达式树 修改表达 ...

  3. 用五分钟重温委托,匿名方法,Lambda,泛型委托,表达式树

    这些对老一代的程序员都是老生常谈的东西,没什么新意,对新生代的程序员却充满着魅力.曾经新生代,好多都经过漫长的学习,理解,实践才能掌握委托,表达式树这些应用.今天我尝试用简单的方法叙述一下,让大家在五 ...

  4. 转帖:用五分钟重温委托,匿名方法,Lambda,泛型委托,表达式树

    用五分钟重温委托,匿名方法,Lambda,泛型委托,表达式树 这些对老一代的程序员都是老生常谈的东西,没什么新意,对新生代的程序员却充满着魅力.曾经新生代,好多都经过漫长的学习,理解,实践才能掌握委托 ...

  5. 表达式树(Expression Tree)

    饮水思源 本文并非原创而是下面网址的一个学习笔记 https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/e ...

  6. C# 知识回顾 - 表达式树 Expression Trees

    C# 知识回顾 - 表达式树 Expression Trees 目录 简介 Lambda 表达式创建表达式树 API 创建表达式树 解析表达式树 表达式树的永久性 编译表达式树 执行表达式树 修改表达 ...

  7. 利用表达式树Expression优化反射性能

    最近做了一个.Net Core环境下,基于NPOI的Excel导入导出以及Word操作的服务封装,涉及到大量反射操作,在性能优化过程中使用到了表达式树,记录一下. Excel导入是相对比较麻烦的一块, ...

  8. 表达式树 Expression

    转载泛型方法动态生成表达式树 Expression public string GetGridJSON(TraderInfo model) { IQueryable<TraderInfo> ...

  9. 委托,匿名方法,Lambda,泛型委托,表达式树

    一.委托:完成一个委托应分三个步骤://step01:首先用delegate定义一个委托;public delegate int CalculatorAdd(int x, int y);//step0 ...

随机推荐

  1. [源码分析] 定时任务调度框架 Quartz 之 故障切换

    [源码分析] 定时任务调度框架 Quartz 之 故障切换 目录 [源码分析] 定时任务调度框架 Quartz 之 故障切换 0x00 摘要 0x01 基础概念 1.1 分布式 1.1.1 功能方面 ...

  2. 用nvm的方式安装node

    一.nvm简介 Node Version Manager(Node版本管理工具)由于以后的开发工作可能会在多个Node版本中测试,而且Node的版本也比较多,所以需要这么款工具来管理.   nvm的安 ...

  3. 网络协议 SNMP- Windows10无简单SNMP协议服务器配置

    原因:Windwos10 1809后更新版本,无启动SNMP协议服务器可选配置项. 解决: 1.打开设置中的[开发人员模式],设置->更新与安全->开发者选项->开发人员模式 2.添 ...

  4. 7.12-7.19 id、w、who、last、lastb、lastlog

    7.12-7.19 id.w.who.last.lastb.lastlog 目录 7.12 id:显示用户与用户组的信息 7.13 w:显示已登录用户信息 7.14 who:显示已登录用户信息 显示最 ...

  5. 3.socket编程示例

    #block_server.py 非阻塞IO示例#有个疑惑:下面的connfd的blockind要设置为True,不然会出错,待解决from socket import *from time impo ...

  6. Linux进阶之Git分布式版本控制系统篇

    一.Git介绍 Git(读音为/gɪt/.)是一个开源的分布式版本控制系统,可以有效.高速的处理从很小到非常大的项目版本管理. Git 是 Linus Torvalds 为了帮助管理 Linux 内核 ...

  7. 一文读懂一条 SQL 查询语句是如何执行的

    2001 年 MySQL 发布 3.23 版本,自此便开始获得广泛应用,随着不断地升级迭代,至今 MySQL 已经走过了 20 个年头. 为了充分发挥 MySQL 的性能并顺利地使用,就必须正确理解其 ...

  8. GO学习-(8) Go语言基础之数组

    Go语言基础之数组 Array(数组) 数组是同一种数据类型元素的集合. 在Go语言中,数组从声明时就确定,使用时可以修改数组成员,但是数组大小不可变化. 基本语法: // 定义一个长度为3元素类型为 ...

  9. Jmeter- 笔记7 - 服务器监控(ServerAgent配置)

    文件:ServerAgent - 2.2.3.zip  放网盘了 在服务器的操作:只需要把这个文件上传到被监控服务器,然后解压,启动sh startagent.sh --udp-port 0 --tc ...

  10. maven项目多环境打包问题

    1.xxx-api是基于springboot的模块 2.配置文件 application.properties spring.profiles.active=@activeEnv@ applicati ...