zoukankan      html  css  js  c++  java
  • 【手撸一个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();
                }
            }
        }
    }
  • 相关阅读:
    Gym 102040B Counting Inversion(超级数位dp)
    Educational Codeforces Round 104 (Rated for Div. 2)(A~D)
    2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1)_组队训练
    线段树板子
    Codeforces Round #700 (Div. 2)
    Codeforces Round #699 (Div. 2)
    Codeforces Round #698 (Div. 2)
    字典树——实现字符串前缀查找(可返回字符串)
    LeetCode146-LRU缓存机制
    用到过的git命令
  • 原文地址:https://www.cnblogs.com/diwu0510/p/10663379.html
Copyright © 2011-2022 走看看