• 【手撸一个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();
                }
            }
        }
    }
  • 相关阅读:
    VB.NET程序设计笔记
    ASP.NET动态的网页增删查改
    一般处理程序加简单三层实现增删查改(2)
    一般处理程序加简单三层实现增删查改(1)
    设计模式六大原则(1):单一职责原则
    Android Https相关完全解析 当OkHttp遇到Https
    Androrid应用打包release版时关闭log日志输出
    Fragment结合ViewPager之懒加载
    多线程基础
    Android Studio wifi调试
  • 原文地址:https://www.cnblogs.com/diwu0510/p/10663379.html
Copyright © 2020-2023  润新知