最近在写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表达式类型的委托。

最新文章

  1. iOS架构师之路:控制器(View Controller)瘦身设计
  2. ExtJs 学习之开篇(二) Observable 给类添加监听
  3. Java AIO 异步IO应用实例
  4. phpexcel操作
  5. Knockout.Js官网学习(html绑定、css绑定)
  6. Codeforces 322B
  7. java基础学习总结四(控制语句&lt;顺序、选择、循环&gt;、方法)
  8. linux mount命令学习
  9. angularJS的一些用法
  10. 机器学习基石笔记:04 Feasibility of Learning
  11. 位运算之——按位与(&amp;)操作——(快速取模算法)
  12. Zsh安装及常用操作
  13. MyBatis Plus:No qualifying bean of type &#39;com.baomidou.mybatisplus.mapper.BaseMapper&lt;?&gt;&#39; available: expected single matching bean but found 4
  14. 26、jQuery
  15. Codeforces 670E - Correct Bracket Sequence Editor - [对顶栈]
  16. 架构模式数据源模式之:表数据入口(Table Data Gateway)、行数据入口(Row Data Gateway)、活动记录(Active Record)
  17. eclipse jetty 请求的操作无法在使用用户映射区域打开的文件上执行
  18. 俞军的PM12条
  19. [LeetCode] 268. Missing Number ☆(丢失的数字)
  20. bzoj3946

热门文章

  1. Java中volatile关键字你真的理解了吗?
  2. VSCode配置MSVC+VSCode使用easyx库,2021.5.13日配置
  3. 吃透KVM创建虚机和KVM命令
  4. 适用于windows10 Linux子系统的安装管理配置 How To Management Windows Subsystem for Linux WSL
  5. [OS] 概述&amp;学习资料
  6. Linux 根目录所在分区被脏数据占满
  7. 070.Python聚焦爬虫数据解析
  8. Docker的镜像理解以及容器的备份、恢复和迁移操作
  9. python 中 list 的append与extend区别
  10. Centos 重置root密码