Expressions
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, @"(?