csharp/17MKH/Mkh/src/02_Data/Data.Core/Internal/ExpressionResolver.cs

ExpressionResolver.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using Mkh.Data.Abstractions.Adapter;
using Mkh.Data.Abstractions.Queryable;
using Mkh.Data.Core.Extensions;
using Mkh.Data.Core.Internal.QueryStructure;

namespace Mkh.Data.Core.Internal;

/// 
/// 表达式解析器
/// 
public clast ExpressionResolver
{
    public static string Resolve(QueryBody queryBody, LambdaExpression expression, IQueryParameters parameters)
    {
        if (expression == null)
            return string.Empty;

        var sqlBuilder = new StringBuilder();

        Resolve(queryBody, expression, expression, sqlBuilder, parameters);

        return sqlBuilder.ToString();
    }

    public static void Resolve(QueryBody queryBody, Expression expression, LambdaExpression fullLambda, StringBuilder sqlBuilder, IQueryParameters parameters)
    {
        switch (expression.NodeType)
        {
            case ExpressionType.Lambda:
                Resolve(queryBody, (expression as LambdaExpression)!.Body, fullLambda, sqlBuilder, parameters);
                break;
            case ExpressionType.Convert:
            case ExpressionType.ConvertChecked:
                Resolve(queryBody, (expression as UnaryExpression)!.Operand, fullLambda, sqlBuilder, parameters);
                break;
            case ExpressionType.Add:
            case ExpressionType.AddChecked:
            case ExpressionType.Subtract:
            case ExpressionType.SubtractChecked:
            case ExpressionType.Multiply:
            case ExpressionType.MultiplyChecked:
            case ExpressionType.Divide:
            case ExpressionType.Modulo:
            case ExpressionType.And:
            case ExpressionType.AndAlso:
            case ExpressionType.Or:
            case ExpressionType.OrElse:
            case ExpressionType.LessThan:
            case ExpressionType.LessThanOrEqual:
            case ExpressionType.GreaterThan:
            case ExpressionType.GreaterThanOrEqual:
            case ExpressionType.Equal:
            case ExpressionType.NotEqual:
            case ExpressionType.Coalesce:
            case ExpressionType.ArrayIndex:
            case ExpressionType.RightShift:
            case ExpressionType.LeftShift:
            case ExpressionType.ExclusiveOr:
                ResolveBinary(queryBody, expression as BinaryExpression, fullLambda, sqlBuilder, parameters);
                break;
            case ExpressionType.Constant:
                AppendValue(queryBody, (expression as ConstantExpression)!.Value, sqlBuilder, parameters);
                break;
            case ExpressionType.MemberAccess:
                ResolveMember(queryBody, expression as MemberExpression, fullLambda, sqlBuilder, parameters);
                break;
            case ExpressionType.Call:
                ResolveCall(queryBody, expression as MethodCallExpression, fullLambda, sqlBuilder, parameters);
                break;
            case ExpressionType.MemberInit:
                ResolveMemberInit(queryBody, expression, fullLambda, sqlBuilder, parameters);
                break;
        }
    }

    /// 
    /// 附加值
    /// 
    public static void AppendValue(QueryBody queryBody, object value, StringBuilder sqlBuilder, IQueryParameters parameters)
    {
        if (value == null)
        {
            var len = sqlBuilder.Length;
            if (sqlBuilder[len - 1] == ' ' && sqlBuilder[len - 2] == '>' && sqlBuilder[len - 3] == '