【手撸一个ORM】第四步、Expression(表达式目录树)扩展
到这里,Orm的基架已经搭起来了,接下来就是激动人心的部分,表达式目录树转Sql语句,SqlDataReader转数据实体等等,但是在这之前,我们需要扩展下表达式目录树的方法,以方便后面的相关操作。
表达式目录树解析时需要的扩展方法
- 表达式操作符转SQL操作符,这个没什么好说的,根据表达式类型获取相应的sql操作符,如 NodeType == ExpressionType.Equal,则返回 " = "。
- 获取MemberExpression的根类型。在园子里表达式目录树相关文章中少有涉及,但这个很重要,在拼接sql语句时,很多时候我们需要根据该类型进行不同的操作,如 根类型为 Parameter,表达式将转换为 [表名].[列名] 字符串,若为其他,则会尝试对表达式进行求值。
- 获取表达式目录路的值,如果是 常数类型,直接返回该节点的值,如果是其他类型,则尝试转为Lambda表达式,并对Lambda表达式进行求值返回。
using System;
using System.Collections.Generic;
using System.Linq.Expressions; namespace MyOrm.Expressions
{
public static class ExpressionExtensions
{
public static string ToSqlOperator(this ExpressionType type)
{
switch (type)
{
case (ExpressionType.AndAlso):
case (ExpressionType.And):
return " AND ";
case (ExpressionType.OrElse):
case (ExpressionType.Or):
return " OR ";
case (ExpressionType.Not):
return " NOT ";
case (ExpressionType.NotEqual):
return "<>";
case ExpressionType.GreaterThan:
return ">";
case ExpressionType.GreaterThanOrEqual:
return ">=";
case ExpressionType.LessThan:
return "<";
case ExpressionType.LessThanOrEqual:
return "<=";
case (ExpressionType.Equal):
return "=";
default:
throw new Exception("不支持该方法");
}
} public static ExpressionType GetRootType(this MemberExpression expression, out Stack<string> stack)
{
var memberExpr = expression;
var parentExpr = expression.Expression; stack = new Stack<string>();
stack.Push(expression.Member.Name); while (parentExpr != null && parentExpr.NodeType == ExpressionType.MemberAccess)
{
memberExpr = (MemberExpression)parentExpr;
parentExpr = ((MemberExpression)parentExpr).Expression;
stack.Push(memberExpr.Member.Name);
} return parentExpr?.NodeType ?? memberExpr.NodeType;
} public static object GetValue(this Expression expression)
{
if (expression.NodeType == ExpressionType.Constant)
{
return ((ConstantExpression)expression).Value;
}
else
{
var cast = Expression.Convert(expression, typeof(object));
return Expression.Lambda<Func<object>>(cast).Compile().Invoke();
}
}
}
}
【手撸一个ORM】第四步、Expression(表达式目录树)扩展的更多相关文章
- 【手撸一个ORM】第一步、实体约定和描述
一.约定 数据实体必须实现 IEntity 接口,该接口定义了一个int类型的Id属性,既每个实体必须有一个名称为Id的自增主键. 若数据表的主键列名称不是Id,可以通过 [MyKey("主 ...
- 【手撸一个ORM】第九步、orm默认配置类 MyDbConfiguration,一次配置,简化实例化流程
这个实现比较简单,事实上可配置的项目很多,如有需要,请读者自行扩展 using System; namespace MyOrm { public class MyDbConfiguration { p ...
- 【手撸一个ORM】MyOrm的使用说明
[手撸一个ORM]第一步.约定和实体描述 [手撸一个ORM]第二步.封装实体描述和实体属性描述 [手撸一个ORM]第三步.SQL语句构造器和SqlParameter封装 [手撸一个ORM]第四步.Ex ...
- 第十五节:Expression表达式目录树(与委托的区别、自行拼接、总结几类实例间的拷贝)
一. 基本介绍 回忆: 最早接触到表达式目录树(Expression)可能要追溯到几年前使用EF早期的时候,发现where方法里的参数是Expression<Func<T,bool> ...
- 【学习笔记】Expression表达式目录树
Expression表达式目录树:一个能拼装能解析的数据结构,语法树. 一.手动拼装表达式目录树 示例1: /// <summary> /// 展示表达式树,协助用的 /// 编译lamb ...
- 【手撸一个ORM】第五步、Expression(表达式目录树)转换为Where子句
说明 在SQL中,查询.修改比较常用到WHERE子句,在这里根据使用场景不同,定义了两个类,一个用于查询,一个用于修改(插入)操作.原因是: 查询操作支持一级导航属性查询,如student.Schoo ...
- 【手撸一个ORM】第六步、对象表达式解析和Select表达式解析
说明 一个Orm自然不仅仅包含条件表达式,还会有如下的场景: OrderBy(s => s.StudentName) Select<StudentDto>(s => new S ...
- 【手撸一个ORM】第七步、SqlDataReader转实体
说明 使用Expression(表达式目录树)转Entity的文章在园子里有很多,思路也大致也一样,我在前面有篇文章对解决思路有些说明,有兴趣的小伙伴可以看下 (传送门),刚接触表达式目录树时写的,不 ...
- Expression表达式目录树
一.初识Expression 1.在上一篇我们讲到了委托(忘记了可以在看看,点赞在看养成习惯),今天要讲的Expression也和委托有一点点关系吧(没有直接关系,只是想要大家看看我其他的文章),Ex ...
随机推荐
- leetcode 43. Multiply Strings(高精度乘法)
Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...
- 解决 ssh 链接慢问题
sed -i 's/GSSAPIAuthentication yes/GSSAPIAuthentication no/' /etc/ssh/sshd_configsed -i '/#UseDNS ye ...
- ACM学习历程—HDU4956 Poor Hanamichi(模拟)
Poor Hanamichi Problem Description Hanamichi is taking part in a programming contest, and he is assi ...
- mysql错误-修改mysql.sock位置
在Mysql下有时候会出现mysql.sock位置错误,导致无法链接数据库. mac下报错的时候: 首先修改my.cnf 位置在/etc/my.cnf下,假如没有的话,去/usr/locate/mys ...
- Poj_1068 Parencodings
S (((( )( )() ) ) ) P-sequence 4 5 6666,表示第i个右括号的左边有几个左括号. W-sequence 1 1 1456,表示第i个右括号和以 ...
- SELinux处理命令
1 查看SELinux状态 Enforcing为开启状态:Disabled为关闭状态. [root@localhost /]# getenforce Enforcing 2 临时关闭SELinux [ ...
- java之字符串转换
参考http://how2j.cn/k/number-string/number-string-parse/317.html 数字转字符串 方法1: 使用String类的静态方法valueOf 方法2 ...
- 使用go实现基于命令行的计算器程序
项目目录结构 calcs.go源文件 package main import ( "fmt" "os" "strconv" "my ...
- python中出现 IndentationError:unindent does not match any outer indentation level
python中出现IndentationError:unindent does not match any outer indentation level 今天在网上copy的一段代码,代码很简单,每 ...
- POJ 2348 Euclid's Game (博弈)
题意:给定两个整数,两个人轮流操作,每次可以用较大数减去较小数的整数倍,当一个数变成0时,则结束,问谁会胜. 析:很明显如果 a == b 那么就可以直接结束了,那么如果 a > b我们可以交换 ...