当前位置: 首页 > 编程语言 > C#

C#表达式树表达式基础讲解分享

时间:2023-04-10 17:18:06 C#

什么是表达式树?表达式树以树状数据结构表示代码,其中每个节点都是一个表达式,例如方法调用和x>expression1=x=>x.年龄>18;返回确定();那么,x.Age>18这个表达式的树结构如下:通过查看变量或者添加VisualStudio自带的监控的方式,我们可以发现树的根节点(NodeType)是GreaterThan,左边节点(Left)为x.Age,右边节点(Right)为18。因此,可以大致画出一个树结构。最后,通过这个树形结构,C#可以帮助我们将表达式编译成具体的SQL执行语句。如果想更清楚的查看表达式树的结构,可以nuget一个包(ExpressionTreeToString)将表达式结构转换成字符串PM>Install-PackageZSpitz.Util-Version0.1.116Expression>表达式=u=>u.Age>=18;vartreeStr=expression.ToString("对象表示法","C#");//输出如下字符串varu=newParameterExpression{Type=typeof(User),IsByRef=false,Name="u"};newExpression>{NodeType=ExpressionType.Lambda,Type=typeof(Func),Parameters=newReadOnlyCollection{u},Body=newBinaryExpression{NodeType=ExpressionType.GreaterThanOrEqual,Type=typeof(bool),Left=newMemberExpression{Type=typeof(int),Expression=u,Member=typeof(User).GetProperty("Age")},Right=newConstantExpression{类型=typeof(int),值=18}},ReturnType=typeof(bool)}Expression和Func的区别Expression存储的是运算逻辑,可以保存为抽象语法树(AST),运行时可以动态获取运算逻辑。func只是存储结果,不能另存为语法树不能动态获取运算逻辑。因此,在EFCore中,在使用表达式查询数据库数据时,我们应该选择Expression而不是Func,因为使用Func,Func中的表达式实际上并不能转化为SQL,而是所有数据加载到内存后,过滤条件在内存中的Func。简单来说,这时候过滤User表中年龄大于18的数据,有两种写法//这种写法,实际生成的SQL语句大概是这样的SELECT*FROMUser作为TWHERET.age>18Expression>expression1=x=>x.Age>18;dbContext.User.Where(expression1).toList();//本例生成语句为SELECT*FROMUser,然后将User表中的数据全部加载到内存中后,filterFuncfunc1=x=>x.Age>18;dbContext.User.Where(func1).toList();通过代码ParameterExpressionBinaryExpressionMethodCallExpressionConstantExpression创建表达式树这些类几乎都没有提供构造方法,所有的属性几乎都是只读的。因此,我们一般不会直接创建这些类的实例,而是调用Expression类的Parameter、MakeBinary、Call、Constant等静态方法来生成它们。这些静态方法一般称为创建表达式树的工厂方法,通过方法参数类设置传递属性。动态表达式:u=>u.Age>=18;通过代码构建一般构建步骤:先创建ParameterExpression然后从内到外依次构建先左节点(Left),再右节点(Right)再Body节点拼接成ExpressionpublicIActionResultGetUserByManualExpression(){ParameterExpressionparameterExpression=Expression.Parameter(type:typeof(User),name:"u");ConstantExpression对=Expression.Constant(18);MemberExpressionleft=Expression.MakeMemberAccess(parameterExpression,member:typeof(User).GetProperty("Age"));BinaryExpressionbody=Expression.GreaterThanOrEqual(left,right);Expression>expression=Expression.Lambda>(body,parameters:parameterExpression);vardata=_userService.GetUsers(表达式);返回确定(新{代码=200,味精=“确定”,数据});}本篇关于C#表达式树Expression的基本讲解到此为止。希望对大家的学习有所帮助,希望大家多多支持。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: