csharp/1448376744/Dapper.Linq/src/Dapper.Common/Expressions/ExpressionActivator.cs

ExpressionActivator.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text.RegularExpressions;

namespace Dapper.Expressions
{
    /// 
    /// 表达式树生成器
    /// 
    public clast ExpressionActivator
    {
        private Dictionary Factorization(string expression)
        {
            var experssions = new Dictionary();
            var pattern = @"\([^\(\)]+\)";
            var text = $"({expression})";
            while (Regex.IsMatch(text, pattern))
            {
                var key = $"${experssions.Count}";
                var value = Regex.Match(text, pattern).Value;
                experssions.Add(key, value);
                text = text.Replace(value, key);
            }
            return experssions;
        }

        private Expression CreateExpression(ParameterExpression parameter, string expression)
        {
            var expressions1 = Factorization(expression);
            var expressions2 = new Dictionary();
            foreach (var item in expressions1)
            {
                var subexpr = item.Value.Trim('(', ')');
                var @opterator = ResovleOperator(item.Value);
                var opt = GetExpressionType(@opterator);
                if (opt == ExpressionType.Not)
                {
                    Expression exp;
                    var text = subexpr.Split(new string[] { @opterator }, StringSplitOptions.RemoveEmptyEntries)[0].Trim();
                    if (expressions2.ContainsKey(text))
                    {
                        exp = expressions2[text];
                    }
                    else if (parameter.Type.GetProperties().Any(a => a.Name == text))
                    {
                        var property = parameter.Type.GetProperty(text);
                        exp = Expression.MakeMemberAccess(parameter, property);
                    }
                    else
                    {
                        exp = Expression.Constant(Convert.ToBoolean(text));
                    }
                    expressions2.Add(item.Key, Expression.MakeUnary(opt, exp, null));
                }
                else
                {
                    var text1 = subexpr
                        .Split(new string[] { @opterator }, StringSplitOptions.RemoveEmptyEntries)[0]
                        .Trim();
                    var text2 = subexpr
                        .Split(new string[] { @opterator }, StringSplitOptions.RemoveEmptyEntries)[1]
                        .Trim();
                    string temp = null;
                    Expression exp1, exp2;
                    //永远将变量放在第一个操作数
                    if (parameter.Type.GetProperties().Any(a => a.Name == text2))
                    {
                        temp = text1;
                        text1 = text2;
                        text2 = temp;
                    }
                    //是否为上一次的分式
                    if (expressions2.ContainsKey(text1))
                    {
                        exp1 = expressions2[text1];
                    }
                    else if (parameter.Type.GetProperties().Any(a => a.Name == text1))
                    {
                        //是否为变量
                        var property = parameter.Type.GetProperty(text1);
                        exp1 = Expression.MakeMemberAccess(parameter, property);
                    }
                    else
                    {
                        exp1 = ResovleConstantExpression(text1);
                    }
                    //是否为上一次的分式
                    if (expressions2.ContainsKey(text2))
                    {
                        exp2 = expressions2[text2];
                    }
                    //如果第一个操作数是变量
                    else if (parameter.Type.GetProperties().Any(a => a.Name == text1))
                    {
                        var constantType = parameter.Type.GetProperty(text1).PropertyType;
                        exp2 = ResovleConstantExpression(text2, constantType);
                    }
                    else
                    {
                        exp2 = ResovleConstantExpression(text1, (exp1 as ConstantExpression)?.Type);
                    }
                    expressions2.Add(item.Key, Expression.MakeBinary(opt, exp1, exp2));
                }
            }
            return expressions2.Last().Value;
        }

        public ExpressionContextResult Create(string expression)
        {
            expression = Initialization(expression);
            var parameter = Expression.Parameter(typeof(T), "p");
            var body = CreateExpression(parameter, expression);
            var lambda = Expression.Lambda(body, parameter);
            var func = lambda.Compile() as Func;
            return new ExpressionContextResult()
            {
                Func = func,
                LambdaExpression = lambda
            };
        }

        private string Initialization(string expression)
        {
            expression = Regex.Replace(expression, @"(?