【手撸一个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 ... 
随机推荐
- css设置文件编码
			在外部css文件的顶部,写入下面代码: @charset "UTF-8"; 
- IoC~MVC3+EF+Autofac实现松耦合的系统架构
			MVC3+EF+Autofac网上这种文章确实没有,呵呵,今天就写一个,代大家分享! 这个系列的文章将带我们进入一种新的开发模式,注入开发模式,或者叫它IOC模式,说起IOC你可以这样去理解它,它为你 ... 
- CentOS 6以下版本 支持Ext4
			CentOS默认是不支持Ext4.所以你需要处理一下才行. 使用环境使用的是CentOS5.8 内核是 2.6.18-238.19.1.el5 其实CentOS 5.8 里面是有 ext4 模块的, ... 
- vue之webpack+vuecli打包生成资源相对引用路径与背景图片的正确引用
			问题描述 一般情况下,通过webpack+vue-cli默认打包的css.js等资源,路径都是绝对的 但当部署到带有文件夹的项目中,这种绝对路径就会出现问题,因为把配置的static文件夹当成了根路径 ... 
- wpf如何获取control template里的元素
			wpf中的控件模板里的元素有自己独立的命名域. 因此不能通过FindName来根据x:Name来查找子节点. 自己写了一个方法, 通过可视树遍历子节点,然后匹配名字. 如下: private stat ... 
- 10 Vue 学习   shortList页面
			1: shortList页面代码如下: <template> <div class="fillcontain"> <head-top></ ... 
- Lagom学习 六 Akka Stream
			lagom中的stream 流数据处理是基于akka stream的,异步的处理流数据的.如下看代码: 流式service好处是: A: 并行: hellos.mapAsync(8, name -& ... 
- git base cli
- c# list排序的实现方式
			实体类实现IComparable接口,而且必须实现CompareTo方法 实体类定义如下: class Info:IComparable { public int Id { get; set; } p ... 
- iview之select选择框选中内容后有空格的问题
			导致原因: option组件格式化造成的.此处</Option>在另一行,只要和输出内容一行,就不会有空格了. <Select :label-in-value="true& ... 
