using System; using System.Collections.Generic; using System.Linq.Expressions; namespace Kean.Infrastructure.Database { /// /// 投影表达式 /// public sealed class MappingExpression : ExpressionVisitor { private readonly List<(string, string)> _columns = new(); // 投影列 private Dictionary _schema; // 对象名 private string _symbol; // 名称符号 private string _alias; // 别名(暂存) private string _function; // 函数(暂存) /// /// 解析表达式 /// public static List<(string, string)> Build(Expression expression, Dictionary schema, string symbol) { var visitor = new MappingExpression { _schema = schema, _symbol = symbol }; visitor.Visit(expression); if (visitor._columns.Count > 0) { return visitor._columns; } throw new Exception(); } /// /// 实现 ExpressionVisitor 类的 VisitMember 方法 /// protected override Expression VisitMember(MemberExpression node) { if (node.Expression is ParameterExpression pe && pe.NodeType == ExpressionType.Parameter) { var column = _schema == null ? $"{_symbol[0]}{node.Member.Name}{_symbol[1]}" : $"{_symbol[0]}{_schema[pe.Name]}{_symbol[1]}.{_symbol[0]}{node.Member.Name}{_symbol[1]}"; _columns.Add(( _function == null ? column : $"{_function}({column})", $"{_symbol[0]}{_alias ?? node.Member.Name}{_symbol[1]}" )); } _alias = null; _function = null; return node; } /// /// 实现 ExpressionVisitor 类的 VisitMethodCall 方法 /// protected override Expression VisitMethodCall(MethodCallExpression node) { if (node.Method.DeclaringType == typeof(Function)) { _function= node.Method.Name.ToUpper(); Visit(node.Arguments[0]); } return node; } /// /// 实现 ExpressionVisitor 类的 VisitNew 方法 /// protected override Expression VisitNew(NewExpression node) { for (int i = 0; i < node.Members.Count; i++) { _alias = node.Members[i].Name; Visit(node.Arguments[i]); } return node; } /// /// 实现 ExpressionVisitor 类的 VisitUnary 方法 /// protected override Expression VisitUnary(UnaryExpression node) { if (node.NodeType == ExpressionType.Convert) { Visit(node.Operand); } return node; } } }