(精华)2020年8月11日 C#基础知识点 解析表达式目录树实现替换
{<!-- -->
//修改表达式目录树
Expression<Func<int, int, int>> exp = (m, n) => m * n + 2;
OperationsVisitor visitor = new OperationsVisitor();
Expression expNew = visitor.Modify(exp);
}
{<!-- -->
Expression<Func<People, bool>> lambda = x => x.Age > 5 && x.Id > 5
&& x.Name.StartsWith("1")
&& x.Name.EndsWith("1")
&& x.Name.Contains("1");
string sql = string.Format("Delete From [{0}] WHERE {1}"
, typeof(People).Name
, " [Age]>5 AND [ID] >5"
);
ConditionBuilderVisitor vistor = new ConditionBuilderVisitor();
vistor.Visit(lambda);
Console.WriteLine(vistor.Condition());
}
{<!-- -->
Expression<Func<People, bool>> lambda = x => x.Age > 5 && x.Name == "A" || x.Id > 5;
ConditionBuilderVisitor vistor = new ConditionBuilderVisitor();
vistor.Visit(lambda);
Console.WriteLine(vistor.Condition());
}
{<!-- -->
Expression<Func<People, bool>> lambda = x => x.Age > 5 || (x.Name == "A" && x.Id > 5);
ConditionBuilderVisitor vistor = new ConditionBuilderVisitor();
vistor.Visit(lambda);
Console.WriteLine(vistor.Condition());
}
{<!-- -->
Expression<Func<People, bool>> lambda = x => (x.Age > 5 || x.Name == "A") && x.Id > 5;
ConditionBuilderVisitor vistor = new ConditionBuilderVisitor();
vistor.Visit(lambda);
Console.WriteLine(vistor.Condition());
}
public class ConditionBuilderVisitor : ExpressionVisitor
{<!-- -->
private Stack<string> _StringStack = new Stack<string>();
public string Condition()
{<!-- -->
string condition = string.Concat(this._StringStack.ToArray());
this._StringStack.Clear();
return condition;
}
/// <summary>
/// 如果是二元表达式
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
protected override Expression VisitBinary(BinaryExpression node)
{<!-- -->
if (node == null) throw new ArgumentNullException("BinaryExpression");
this._StringStack.Push(")");
base.Visit(node.Right);//解析右边
this._StringStack.Push(" " + node.NodeType.ToSqlOperator() + " ");
base.Visit(node.Left);//解析左边
this._StringStack.Push("(");
return node;
}
/// <summary>
///
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
protected override Expression VisitMember(MemberExpression node)
{<!-- -->
if (node == null) throw new ArgumentNullException("MemberExpression");
this._StringStack.Push(" [" + node.Member.Name + "] ");
return node;
}
/// <summary>
/// 常量表达式
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
protected override Expression VisitConstant(ConstantExpression node)
{<!-- -->
if (node == null) throw new ArgumentNullException("ConstantExpression");
this._StringStack.Push(" '" + node.Value + "' ");
return node;
}
/// <summary>
/// 方法表达式
/// </summary>
/// <param name="m"></param>
/// <returns></returns>
protected override Expression VisitMethodCall(MethodCallExpression m)
{<!-- -->
if (m == null) throw new ArgumentNullException("MethodCallExpression");
string format;
switch (m.Method.Name)
{<!-- -->
case "StartsWith":
format = "({0} LIKE {1}+'%')";
break;
case "Contains":
format = "({0} LIKE '%'+{1}+'%')";
break;
case "EndsWith":
format = "({0} LIKE '%'+{1})";
break;
default:
throw new NotSupportedException(m.NodeType + " is not supported!");
}
this.Visit(m.Object);
this.Visit(m.Arguments[0]);
string right = this._StringStack.Pop();
string left = this._StringStack.Pop();
this._StringStack.Push(String.Format(format, left, right));
return m;
}
}
public class OperationsVisitor : ExpressionVisitor
{<!-- -->
public Expression Modify(Expression expression)
{<!-- -->
return this.Visit(expression);
}
protected override Expression VisitBinary(BinaryExpression b)
{<!-- -->
if (b.NodeType == ExpressionType.Add)
{<!-- -->
Expression left = this.Visit(b.Left);
Expression right = this.Visit(b.Right);
return Expression.Subtract(left, right);
}
return base.VisitBinary(b);
}
protected override Expression VisitConstant(ConstantExpression node)
{<!-- -->
return base.VisitConstant(node);
}
}