简介
- 表达式树,当前只是我抄袭别人的代码,基本的逻辑和应该如何扩展我还是不清楚,所以不做过多简介,等我之后弄清楚我会继续更新。这篇主要是为了有个参考的代码(写的简洁比较逻辑较清晰),同时也是为了可以随时查看,上传到博客记录。
基本代码
public class MyExpression : ExpressionVisitor
{
private Stack<string> values = new Stack<string>();
public MyExpression()
{
}
public string Condition()
{
var condition = string.Concat(values.ToArray());
values.Clear();
return condition;
}
public string ToSqlOpearator(ExpressionType expressionType)
{
var op = default(string);
switch (expressionType)
{
case ExpressionType.Add:
break;
case ExpressionType.AddChecked:
break;
case ExpressionType.And:
break;
case ExpressionType.AndAlso:
op = "AND";
break;
case ExpressionType.ArrayLength:
break;
case ExpressionType.ArrayIndex:
break;
case ExpressionType.Call:
break;
case ExpressionType.Coalesce:
break;
case ExpressionType.Conditional:
break;
case ExpressionType.Constant:
break;
case ExpressionType.Convert:
break;
case ExpressionType.ConvertChecked:
break;
case ExpressionType.Divide:
break;
case ExpressionType.Equal:
op = "=";
break;
case ExpressionType.ExclusiveOr:
break;
case ExpressionType.GreaterThan:
op = ">";
break;
default:
break;
}
return op;
}
protected override Expression VisitBinary(BinaryExpression node)
{
Console.WriteLine($"node {node}");
if (node == null)
{
return null;
}
values.Push(")");
Visit(node.Right);
values.Push($"{ToSqlOpearator(node.NodeType)}");
Visit(node.Left);
values.Push("(");
return node;
}
protected override Expression VisitMember(MemberExpression node)
{
if (node == null)
{
return null;
}
values.Push(node.Member.Name);
return node;
}
protected override Expression VisitConstant(ConstantExpression node)
{
if (node == null)
{
return null;
}
values.Push(node.Value.ToString());
return node;
}
protected override Expression VisitMethodCall(MethodCallExpression node)
{
if (node == null)
{
return null;
}
Visit(node.Object);
Visit(node.Arguments[0]);
var right = values.Pop();
var left = values.Pop();
switch (node.Method.Name)
{
case "StartsWith":
values.Push($"({left} LIKE '{right}%')");
break;
default:
break;
}
return node;
}
}
Expression<Func<User, bool>> exp = (x) => x.Name.StartsWith("Peng") && x.Age > 18 && x.Age == 10;
var myExpression = new MyExpression();
myExpression.Visit(exp);
var sql = myExpression.Condition();
待续