表达式树以树形数据结构表示代码,其中每一个节点都是一种表达式,比如方法调用和 x < y 这样的二元运算等。可以对表达式树中的代码进行编辑和运算。 这样能够动态修改可执行代码、在不同数据库中执行 linq 查询以及创建动态查询。 表达式树还能用于动态语言运行时 (dlr) 以提供动态语言和 .net 之间的互操作性,同时保证编译器编儿童谜语大全3到6岁写员能够发射表达式树而非 microsoft 中间语言 (msil)。 这段话是来自官网( [表达式树 (c#) | microsoft docs](表达式树 (c#) | microsoft docs) )的定义。
在 c# 中,我们可以通过 expression 的方式来手动创建表达式树,比如:
[httpget]public iactionresult expression(){ // 查询 年龄age 大于 18 的元素 expression<func<ur,bool>> expression1 = x => x.age > 18; return ok();}
那么,x.age > 18 这一表达式,它的树状结构是这样的:
通过 visual studio 自带的查看变量或添加监视的方式,我们可以发现其中 树的根节点(nodetype)是 greaterthan,左节点(left)是 x.age,右节点(right)是 18。所以由此就可以大概画出树状结构。
最后,通过这种树状结构,c# 就可以帮我们将表达式编译成具体的 sql 执行语句。
如果想更清晰的查看表达式树的结构,可以 nuget 一个包( expressiontreetostring ),将表达式结构转换成字符串
pm> install-package zspitz.util -version 0.1.116
expression<func<ur, bool>> expression = u => u.age >= 18;var treestr = expression.tostring("object notation", "c#");// 输出为下面字符串var u = new parameterexpression { type = typeof(ur), isbyref = fal, name = "u"};new expression<func<ur, bool>> { nodetype = expressiontype.lambda, type = typeof(func<ur, bool>), parameters = new readonlycollection<parameterexpression> { u }, body = new binaryexpression { nodetype = expressiontype.greaterthanorequal, type = typeof(bool), left = new memberexpression { type = typeof(int), expression = u, member = typeof(ur).getproperty("age") }, right = new constantexpression { type = typeof(int), value = 18 } }, returntype = typeof(bool)}
所以,在 efcore 中,使用表达式对数据库数据进行查询中,我们应该选择 expression 而不是 func,因为使用了 func ,实际上并无法将 func 中的表达式转换成 sql,而是在将所有数据加载到内存后,在内存中在过滤 func 中的条件。
简单来说就是,此时要筛选 ur 表中年龄大于18的数据,可以有这两种写法
// 这种写法,实际生成的 sql 语句, 大概是这样的 lect * from ur as t where t.age > 18expre命运共同体作文ssion<func<ur,bool>> expression1 = x => x.age > 18;dbcontext.ur.where(expression1).tolist();// 而这种, 生成的语句是这样的 lect * from u中国一共多少个市r, 然后将 ur 表中所有数据加载到内存中后, 在进行 age > 18 的过滤func<ur, bool> func1 = x => x.age > 18;dbc健康状况填什么ontext.ur.where(func1).tolist();
这些类几乎都没有提供构造方法,而且所有的属性都几乎只是只读。因此我们一般不会直接创建这些类的实例,而是调用 expression 类的 parameter、makebinary、call、constant等静态方法来生成,这些静态方法我们一般称作创建表达式树的工厂方法,而属性则通过方法参数类设置。
动态将表达式:u => u.age >= 18; 通过代码构建出来
一般构建步骤:
先创建 parameterexpression接着由里到外逐步构建先左节点(left)后右节点(right)接着body节点将其拼接成 expressionpublic iactionr依依墟里烟esult geturbymanualexpression(){ parameterexpression parameterexpression = expression.parameter(type:typeof(ur), name: "u"); constantexpression right = expression.constant(18); memberexpression left = expression.makememberaccess(parameterexpression, member: typeof(ur).getproperty("age")); binaryexpression body = expression.greaterthanorequal(left, right); expression<func<ur, bool>> expression = expression.lambda<func<ur, bool>>(body, parameters: parameterexpression); var data = _urrvice.geturs(expression); return ok(new { code = 200, msg = "ok", data });}
到此这篇关于c#表达式树expression基础讲解的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持www.887551.com。
本文发布于:2023-04-04 07:10:54,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/e2000f98ff5bc55b771e4b8411632ceb.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:C#表达式树Expression基础讲解.doc
本文 PDF 下载地址:C#表达式树Expression基础讲解.pdf
留言与评论(共有 0 条评论) |