protected override Expression VisitMemberInit(MemberInitExpression node) { foreach (MemberAssignment binding in node.Bindings) { var visitor = new MemberExpressionVisitor(Context); visitor.Visit(binding.Expression); visitor.SelectedColumn.Alias = binding.Member.Name; Columns.Add(visitor.SelectedColumn); Context.Columns.Add(binding.Member.Name, visitor.SelectedColumn); } return node; }
protected override Expression VisitMemberInit(MemberInitExpression node) { var results = new Dictionary<string, object>(); foreach (MemberAssignment binding in node.Bindings) { var visitor = new MemberExpressionVisitor(Context); visitor.Visit(binding.Expression); if (visitor.Token.Type != TokenType.Object) { throw new NotSupportedException("不支持"); } results.Add(binding.Member.Name, visitor.Token.Object); } Token = Token.Create(results); return node; }
Token ParseArgument(Expression argExp) { if (argExp.NodeType == ExpressionType.Convert || argExp.NodeType == ExpressionType.ConvertChecked) { argExp = ((UnaryExpression)argExp).Operand; } if (argExp.NodeType == ExpressionType.MemberAccess || argExp.NodeType == ExpressionType.Call) { var visitor = new MemberExpressionVisitor(Context); visitor.Visit(argExp); if (visitor.Token.Type == TokenType.Column) { _isColumn = true; } return visitor.Token; //if (visitor.Token.Type == TokenType.Object) //{ //} //else if (visitor.Token.Type == TokenType.Column) //{ // Type = MemberExpressionType.Column; //} //else //{ // throw new Exception(); //} //return visitor.Result; } else if (argExp.NodeType == ExpressionType.Constant) { return Token.Create(((ConstantExpression)argExp).Value); } else { throw new Exception(); } }
Token ParseArgument(Expression argExp) { if (argExp.NodeType == ExpressionType.Convert || argExp.NodeType == ExpressionType.ConvertChecked) { argExp = ((UnaryExpression)argExp).Operand; } if (argExp.NodeType == ExpressionType.MemberAccess || argExp.NodeType == ExpressionType.Call) { var visitor = new MemberExpressionVisitor(Context); visitor.Visit(argExp); if (visitor.Token.Type == TokenType.Column) { _isColumn = true; } return(visitor.Token); //if (visitor.Token.Type == TokenType.Object) //{ //} //else if (visitor.Token.Type == TokenType.Column) //{ // Type = MemberExpressionType.Column; //} //else //{ // throw new Exception(); //} //return visitor.Result; } else if (argExp.NodeType == ExpressionType.Constant) { return(Token.Create(((ConstantExpression)argExp).Value)); } else { throw new Exception(); } }
Token ParseMathBinary(BinaryExpression node) { ExpressionVisitorBase leftVisitor, rightVisitor; if (node.Left is BinaryExpression) { leftVisitor = new BinaryExpressionVisitor(Context); } else { leftVisitor = new MemberExpressionVisitor(Context); } leftVisitor.Visit(node.Left); var leftResult = leftVisitor.Token; if (node.Right is BinaryExpression) { rightVisitor = new BinaryExpressionVisitor(Context); } else { rightVisitor = new MemberExpressionVisitor(Context); } rightVisitor.Visit(node.Right); var rightResult = rightVisitor.Token; if (leftResult.Type == TokenType.Object && rightResult.Type == TokenType.Object) { if (leftResult.Object == null && rightResult.Object == null) { return(Token.Create(true)); } if (leftResult == null || rightResult == null) { return(Token.Create(false)); } if (leftResult.Type == TokenType.Object) { if (leftResult.Object is string || leftResult.Object is bool || leftResult.Object is bool?) { return(Token.Create(leftResult.Equals(rightResult))); } #region 比大小 if (leftResult.Object is DateTime || leftResult.Object is DateTime?) { var left = Convert.ToDateTime(leftResult.Object); var right = Convert.ToDateTime(rightResult.Object); switch (node.NodeType) { case ExpressionType.LessThan: return(Token.Create(left < right)); case ExpressionType.LessThanOrEqual: return(Token.Create(left <= right)); case ExpressionType.Equal: return(Token.Create(left = right)); case ExpressionType.GreaterThan: return(Token.Create(left > right)); case ExpressionType.GreaterThanOrEqual: return(Token.Create(left >= right)); default: throw new Exception(); } } else if (leftResult.Object is int || leftResult.Object is int?) { var left = Convert.ToInt32(leftResult.Object); var right = Convert.ToInt32(rightResult.Object); switch (node.NodeType) { case ExpressionType.LessThan: return(Token.Create(left < right)); case ExpressionType.LessThanOrEqual: return(Token.Create(left <= right)); case ExpressionType.Equal: return(Token.Create(left = right)); case ExpressionType.GreaterThan: return(Token.Create(left > right)); case ExpressionType.GreaterThanOrEqual: return(Token.Create(left >= right)); default: throw new Exception(); } } else if (leftResult.Object is short || leftResult.Object is short?) { var left = Convert.ToInt16(leftResult.Object); var right = Convert.ToInt16(rightResult.Object); switch (node.NodeType) { case ExpressionType.LessThan: return(Token.Create(left < right)); case ExpressionType.LessThanOrEqual: return(Token.Create(left <= right)); case ExpressionType.Equal: return(Token.Create(left = right)); case ExpressionType.GreaterThan: return(Token.Create(left > right)); case ExpressionType.GreaterThanOrEqual: return(Token.Create(left >= right)); default: throw new Exception(); } } else if (leftResult.Object is long || leftResult.Object is long?) { var left = Convert.ToInt64(leftResult.Object); var right = Convert.ToInt64(rightResult.Object); switch (node.NodeType) { case ExpressionType.LessThan: return(Token.Create(left < right)); case ExpressionType.LessThanOrEqual: return(Token.Create(left <= right)); case ExpressionType.Equal: return(Token.Create(left = right)); case ExpressionType.GreaterThan: return(Token.Create(left > right)); case ExpressionType.GreaterThanOrEqual: return(Token.Create(left >= right)); default: throw new Exception(); } } else { return(Token.Create(leftResult.Object == rightResult.Object)); } #endregion } else { throw new Exception(); } } else if (leftResult.Type == TokenType.Column && rightResult.Type == TokenType.Object) { var condition = new Condition(); condition.Left = leftResult; condition.CompareType = SelectMathCompareType(node.NodeType); condition.Right = Token.Create(rightResult.Object); return(Token.Create(condition)); } else if (leftResult.Type == TokenType.Condition && rightResult.Type == TokenType.Object) { var condition = new Condition(); condition.Left = leftResult; condition.CompareType = SelectMathCompareType(node.NodeType); condition.Right = Token.Create(rightResult.Object); return(Token.Create(condition)); } else { throw new Exception(); } throw new Exception(); }
protected override System.Linq.Expressions.Expression VisitMethodCall(System.Linq.Expressions.MethodCallExpression node) { var leftTable = node.Arguments[0]; if (leftTable.NodeType == ExpressionType.Call) { var leftCallExp = leftTable as MethodCallExpression; if (leftCallExp.Method.Name == "NoLock") { leftTable = leftCallExp.Arguments[0]; } } //JoinExpressionVisitor visitor = null; var joinName = "<>" + Path.GetRandomFileName(); if (leftTable.NodeType == ExpressionType.Call) { var leftMethodCallExp = (MethodCallExpression)leftTable; var visitorSub = new JoinExpressionVisitor(Context); visitorSub.Visit(leftTable); if (node.Method.Name == "SelectMany") { SelectExpression = node.Arguments[2]; joinName = ((ParameterExpression)((LambdaExpression)((UnaryExpression)node.Arguments[2]).Operand).Parameters[1]).Name; var joinTmps = visitorSub.Joins; var lastJoin = joinTmps.LastOrDefault(); joinTmps.Remove(lastJoin.Key); // var lockTables = visitor.Result as List<string>; Joins.Add(joinName, lastJoin.Value); //foreach (var item in joinTmps) //{ // if (item.Key == lastJoin.Key) // { // continue; // } // Joins.Add(item.Key, item.Value); //} return(node); } //foreach (var item in visitorSub.Joins) //{ // Joins.Add(item.Key, item.Value); //} } SelectExpression = node.Arguments[4]; //if (leftTable.NodeType == ExpressionType.Call && // (((MethodCallExpression)leftTable).Method.Name == "SelectMany" || // _joinMethodNames.Contains(((MethodCallExpression)leftTable).Method.Name))) //{ // visitor = new JoinExpressionVisitor(); // visitor.Visit(leftTable); // foreach (var item in visitor.Joins) // { // Joins.Add(item.Key, item.Value); // } // //((List<Join>)Result).AddRange((List<Join>)visitor.Result); // if (node.Method.Name == "SelectMany") // { // return node; // } //} var rightTable = node.Arguments[1]; //var nolockRightTable = false; if (rightTable.NodeType == ExpressionType.Call) { var rightCallExp = (MethodCallExpression)rightTable; if (rightCallExp.Method.Name != "NoLock") { throw new Exception(); } //nolockRightTable = true; rightTable = rightCallExp.Arguments[0]; } if (rightTable.NodeType != ExpressionType.Constant) { throw new Exception(); } var leftColumnExp = node.Arguments[2]; var rightColumnExp = node.Arguments[3]; var memVisitor = new MemberExpressionVisitor(Context); memVisitor.Visit(leftColumnExp); if (memVisitor.Token.Type != TokenType.Column) { throw new Exception(); } var join = new Join(); join.Left = memVisitor.Token.Column; memVisitor = new MemberExpressionVisitor(Context); memVisitor.Visit(rightColumnExp); join.Right = memVisitor.Token.Column; //if (nolockRightTable) //{ // ((List<string>)Result).Add(join.Right.Table.Alias); //} switch (node.Method.Name) { case "Join": join.JoinType = JoinType.Inner; break; case "GroupJoin": join.JoinType = JoinType.Left; break; default: throw new Exception(); } var resultExp = node.Arguments[4]; var resultCallExp = (LambdaExpression)((LambdaExpression)((UnaryExpression)resultExp).Operand); Joins.Add(joinName, join); return(node); }
Token ParseNotExpression(UnaryExpression unaryExpression) { var operand = unaryExpression.Operand; if (operand is MemberExpression) { var visitor = new MemberExpressionVisitor(Context); visitor.Visit(operand); switch (visitor.Token.Type) { case TokenType.Object: if (visitor.Token.IsBool()) { return(Token.Create(!((bool)visitor.Token.Object))); } else { throw new Exception("不支持"); } case TokenType.Column: if (operand.Type == typeof(bool) || operand.Type == typeof(bool?)) { return(Token.Create(new Condition() { CompareType = CompareType.Equal, Left = Token.Create(1), Right = Token.Create(1) })); } return(Token.Create(new Condition() { Left = visitor.Token, CompareType = CompareType.Not })); default: throw new Exception(); } } else if (operand is MethodCallExpression) { var visitor = new MethodCallExpressionVisitor(Context); visitor.Visit(operand); var token = visitor.Token; switch (token.Type) { case TokenType.Column: return(Token.Create(new Condition() { Left = token, CompareType = CompareType.Not })); case TokenType.Condition: return(Token.Create(new Condition() { Left = Token.Create(token.Condition), CompareType = CompareType.Not })); case TokenType.Object: return(Token.Create(!((bool)token.Object))); default: throw new Exception(); } } else { throw new Exception("不支持"); } throw new Exception(); }
private void VisitSortExpression(KeyValuePair<string, Expression> sortExpression) { var visitor = new MemberExpressionVisitor(_context); visitor.Visit(sortExpression.Value); if (visitor.Token.Type == TokenType.Column) { _sortColumns.Add(new KeyValuePair<string, Column>(sortExpression.Key, visitor.Token.Column)); return; } throw new Exception(); }
private void VisitAggreationExpression(KeyValuePair<string, Expression> aggreationExpression) { if (aggreationExpression.Value != null) { var visitor = new MemberExpressionVisitor(_context); visitor.Visit(aggreationExpression.Value); if (visitor.Token.Type != TokenType.Column) { throw new Exception("只能针对列进行聚合操作"); } _aggregationColumns.Add(aggreationExpression.Key, visitor.Token.Column); } else { _aggregationColumns.Add(aggreationExpression.Key, null); } }
protected override System.Linq.Expressions.Expression VisitMethodCall(System.Linq.Expressions.MethodCallExpression node) { var leftTable = node.Arguments[0]; if (leftTable.NodeType == ExpressionType.Call) { var leftCallExp = leftTable as MethodCallExpression; if (leftCallExp.Method.Name == "NoLock") { leftTable = leftCallExp.Arguments[0]; } } //JoinExpressionVisitor visitor = null; var joinName = "<>" + Path.GetRandomFileName(); if (leftTable.NodeType == ExpressionType.Call) { var leftMethodCallExp = (MethodCallExpression)leftTable; var visitorSub = new JoinExpressionVisitor(Context); visitorSub.Visit(leftTable); if (node.Method.Name == "SelectMany") { SelectExpression = node.Arguments[2]; joinName = ((ParameterExpression)((LambdaExpression)((UnaryExpression)node.Arguments[2]).Operand).Parameters[1]).Name; var joinTmps = visitorSub.Joins; var lastJoin = joinTmps.LastOrDefault(); joinTmps.Remove(lastJoin.Key); // var lockTables = visitor.Result as List<string>; Joins.Add(joinName, lastJoin.Value); //foreach (var item in joinTmps) //{ // if (item.Key == lastJoin.Key) // { // continue; // } // Joins.Add(item.Key, item.Value); //} return node; } //foreach (var item in visitorSub.Joins) //{ // Joins.Add(item.Key, item.Value); //} } SelectExpression = node.Arguments[4]; //if (leftTable.NodeType == ExpressionType.Call && // (((MethodCallExpression)leftTable).Method.Name == "SelectMany" || // _joinMethodNames.Contains(((MethodCallExpression)leftTable).Method.Name))) //{ // visitor = new JoinExpressionVisitor(); // visitor.Visit(leftTable); // foreach (var item in visitor.Joins) // { // Joins.Add(item.Key, item.Value); // } // //((List<Join>)Result).AddRange((List<Join>)visitor.Result); // if (node.Method.Name == "SelectMany") // { // return node; // } //} var rightTable = node.Arguments[1]; //var nolockRightTable = false; if (rightTable.NodeType == ExpressionType.Call) { var rightCallExp = (MethodCallExpression)rightTable; if (rightCallExp.Method.Name != "NoLock") { throw new Exception(); } //nolockRightTable = true; rightTable = rightCallExp.Arguments[0]; } if (rightTable.NodeType != ExpressionType.Constant) { throw new Exception(); } var leftColumnExp = node.Arguments[2]; var rightColumnExp = node.Arguments[3]; var memVisitor = new MemberExpressionVisitor(Context); memVisitor.Visit(leftColumnExp); if (memVisitor.Token.Type != TokenType.Column) { throw new Exception(); } var join = new Join(); join.Left = memVisitor.Token.Column; memVisitor = new MemberExpressionVisitor(Context); memVisitor.Visit(rightColumnExp); join.Right = memVisitor.Token.Column; //if (nolockRightTable) //{ // ((List<string>)Result).Add(join.Right.Table.Alias); //} switch (node.Method.Name) { case "Join": join.JoinType = JoinType.Inner; break; case "GroupJoin": join.JoinType = JoinType.Left; break; default: throw new Exception(); } var resultExp = node.Arguments[4]; var resultCallExp = (LambdaExpression)((LambdaExpression)((UnaryExpression)resultExp).Operand); Joins.Add(joinName, join); return node; }
private void VisitUpdateExpression(Expression updateExpression) { if (updateExpression == null) { return; } var visitor = new MemberExpressionVisitor(_context); visitor.Visit(updateExpression); if (visitor.Token.Type != TokenType.Object) { throw new NotSupportedException("不支持"); } UpdateResult = (Dictionary<string, object>)visitor.Token.Object; }
protected override Expression VisitMethodCall(MethodCallExpression node) { var argsExp = node.Arguments; var args = new List <Token>(); foreach (var argExp in argsExp) { args.Add(ParseArgument(argExp)); } if (node.Object == null) { //静态方法调用var col = (Token)body.Result; var method = node.Method; if (_isColumn) { //string converter = "{0}"; var parameters = new List <object>(); switch (method.Name) { case "ToDateTime": //if (method.DeclaringType != typeof(Convert) || argsExp.Count != 1) //{ // throw new Exception("不支持"); //} Token = (Token)args[0]; parameters.AddRange(args.Skip(1)); //converter = Token.Column.Converter; //if (string.IsNullOrWhiteSpace(converter)) //{ // converter = "{0}"; //} //switch (Token.Type) //{ // case TokenType.Column: // converter = string.Format(converter, "CONVERT(DATETIME,{0},211)"); // Token.Column.Converter = converter; // break; // default: // throw new Exception(); //} break; case "Contains": Token = (Token)args[1]; //var list = ((Token)args[0]).Object as IList<int>; parameters.Add(args[0].Object); parameters.AddRange(args.Skip(2).Where(x => x.Type == TokenType.Object).Select(x => x.Object)); //if (method.DeclaringType != typeof(Enumerable)) //{ // throw new Exception("不支持"); //} //converter = string.Format(converter, "{0} in (" + string.Join(",", list) + ")"); //Token.Column.Converter = converter; break; default: throw new Exception(); } var converter = new ColumnConverter(method, parameters); Token.Column.Converters.Push(converter); } else { Token = Token.Create(node.Method.Invoke(null, args.Select(x => x.Object).ToArray())); } } else { var body = new MemberExpressionVisitor(Context); body.Visit(node.Object); if (body.Token.Type == TokenType.Column && !_isColumn) { //实例对象是列,参数不是列 Token = body.Token; //string converter = Token.Column.Converter; //if (string.IsNullOrWhiteSpace(converter)) //{ // converter = "{0}"; //} var method = node.Method; var argObjects = args.Select(x => x.Object); //Token.Column.ConverterParameters.AddRange(argObjects); Token.Column.Converters.Push(new ColumnConverter(method, argObjects.ToList(), true)); //switch (method.Name) //{ // case "ToDateTime": // if (method.DeclaringType != typeof(Convert) || argsExp.Count != 1) // { // throw new Exception("不支持"); // } // converter = string.Format(converter, "CONVERT(DATETIME,{0},211)"); // break; // case "Substring": // if (method.DeclaringType != typeof(string)) // { // throw new Exception("不支持"); // } // if (argsExp.Count == 1) // { // //SubString(startIndex) // ExpressionVisitorBase visitor = new PropertyFieldExpressionVisitor(Context); // visitor.Visit(argsExp[0]); // if (visitor.Token.Type != TokenType.Object) // { // throw new Exception("不支持"); // } // converter = string.Format(converter, "SUBSTRING({0}," + (Convert.ToInt32(argObjects[0]) + 1) + ",LEN({0})+1-" + Convert.ToInt32(visitor.Token.Object) + ")"); // } // else if (argsExp.Count == 2) // { // //SubString(startIndex,length) // ExpressionVisitorBase startVisitor = new PropertyFieldExpressionVisitor(Context); // startVisitor.Visit(argsExp[0]); // if (startVisitor.Token.Type != TokenType.Object) // { // throw new Exception("不支持"); // } // ExpressionVisitorBase lenVistior = new PropertyFieldExpressionVisitor(Context); // lenVistior.Visit(argsExp[1]); // if (lenVistior.Token.Type != TokenType.Object) // { // throw new Exception("不支持"); // } // converter = string.Format(converter, "SUBSTRING({0}," + (Convert.ToInt32(startVisitor.Token.Object) + 1) + "," + Convert.ToInt32(lenVistior.Token.Object) + ")"); // } // else // { // throw new Exception("不支持"); // } // break; // case "Contains": // if (method.DeclaringType == typeof(string)) // { // converter = string.Format(converter, "CHARINDEX(@param1,{0})>0"); // Token.Column.ConverterParameters.AddRange(argObjects); // } // else // { // throw new Exception("不支持"); // } // break; // case "StartsWith": // if (method.DeclaringType == typeof(string)) // { // converter = string.Format(converter, "CHARINDEX(@param1,{0})=1"); // Token.Column.ConverterParameters.AddRange(argObjects); // } // else // { // throw new Exception("不支持"); // } // break; // case "AddDays": // if (method.DeclaringType == typeof(DateTime)) // { // converter = string.Format(converter, "DATEADD(DAY,@param1,{0})"); // Token.Column.ConverterParameters.AddRange(argObjects); // } // else // { // throw new Exception("不支持"); // } // break; // case "AddHours": // if (method.DeclaringType == typeof(DateTime)) // { // converter = string.Format(converter, "DATEADD(HOUR,@param1,{0})"); // Token.Column.ConverterParameters.AddRange(argObjects); // } // else // { // throw new Exception("不支持"); // } // break; // case "AddMilliseconds": // if (method.DeclaringType == typeof(DateTime)) // { // converter = string.Format(converter, "DATEADD(MILLISECOND,@param1,{0})"); // Token.Column.ConverterParameters.AddRange(argObjects); // } // else // { // throw new Exception("不支持"); // } // break; // case "AddMinutes": // if (method.DeclaringType == typeof(DateTime)) // { // converter = string.Format(converter, "DATEADD(MINUTE,@param1,{0})"); // Token.Column.ConverterParameters.AddRange(argObjects); // } // else // { // throw new Exception("不支持"); // } // break; // case "AddMonths": // if (method.DeclaringType == typeof(DateTime)) // { // converter = string.Format(converter, "DATEADD(MONTH,@param1,{0})"); // Token.Column.ConverterParameters.AddRange(argObjects); // } // else // { // throw new Exception("不支持"); // } // break; // case "AddSeconds": // if (method.DeclaringType == typeof(DateTime)) // { // converter = string.Format(converter, "DATEADD(SECOND,@param1,{0})"); // Token.Column.ConverterParameters.AddRange(argObjects); // } // else // { // throw new Exception("不支持"); // } // break; // case "AddYears": // if (method.DeclaringType == typeof(DateTime)) // { // converter = string.Format(converter, "DATEADD(YEAR,@param1,{0})"); // Token.Column.ConverterParameters.AddRange(argObjects); // } // else // { // throw new Exception("不支持"); // } // break; // default: // throw new Exception(); //} //Token.Column.Converter = converter; } else if (body.Token.Type == TokenType.Object && !_isColumn) { Token = Token.Create(node.Method.Invoke(body.Token.Object, args.Select(x => x.Object).ToArray())); } else if (body.Token.Type == TokenType.Object && _isColumn) { Token = args[0]; var parameters = new List <object>(); parameters.Add(body.Token.Object); parameters.AddRange(args.Skip(1)); Token.Column.Converters.Push(new ColumnConverter(node.Method, parameters, false)); //string converter = Token.Column.Converter; //if (string.IsNullOrWhiteSpace(converter)) //{ // converter = "{0}"; //} //var method = node.Method; //switch (method.Name) //{ // case "Contains": // if (method.DeclaringType == typeof(string)) // { // converter = string.Format(converter, "CHARINDEX({0},@param1)>0"); // } // else // { // throw new Exception("不支持"); // } // break; // case "StartsWith": // if (method.DeclaringType == typeof(string)) // { // converter = string.Format(converter, "CHARINDEX(@param1,{0})>0"); // } // else // { // throw new Exception("不支持"); // } // break; // case "AddDays": // if (method.DeclaringType == typeof(DateTime)) // { // converter = string.Format(converter, "DATEADD(DAY,{0},@param1)"); // } // else // { // throw new Exception("不支持"); // } // break; // case "AddHours": // if (method.DeclaringType == typeof(DateTime)) // { // converter = string.Format(converter, "DATEADD(HOUR,{0},@param1)"); // } // else // { // throw new Exception("不支持"); // } // break; // case "AddMilliseconds": // if (method.DeclaringType == typeof(DateTime)) // { // converter = string.Format(converter, "DATEADD(MILLISECOND,{0},@param1)"); // } // else // { // throw new Exception("不支持"); // } // break; // case "AddMinutes": // if (method.DeclaringType == typeof(DateTime)) // { // converter = string.Format(converter, "DATEADD(MINUTE,{0},@param1)"); // } // else // { // throw new Exception("不支持"); // } // break; // case "AddMonths": // if (method.DeclaringType == typeof(DateTime)) // { // converter = string.Format(converter, "DATEADD(MONTH,{0},@param1)"); // } // else // { // throw new Exception("不支持"); // } // break; // case "AddSeconds": // if (method.DeclaringType == typeof(DateTime)) // { // converter = string.Format(converter, "DATEADD(SECOND,{0},@param1)"); // } // else // { // throw new Exception("不支持"); // } // break; // case "AddYears": // if (method.DeclaringType == typeof(DateTime)) // { // converter = string.Format(converter, "DATEADD(YEAR,{0},@param1)"); // } // else // { // throw new Exception("不支持"); // } // break; // default: // throw new Exception("不支持"); //} //Token.Column.Converter = converter; //Token.Column.ConverterParameters.Add(body.Token.Object); } else { throw new Exception(); } } return(node); }
protected override Expression VisitMethodCall(MethodCallExpression node) { var argsExp = node.Arguments; var args = new List<Token>(); foreach (var argExp in argsExp) { args.Add(ParseArgument(argExp)); } if (node.Object == null) { //静态方法调用var col = (Token)body.Result; var method = node.Method; if (_isColumn) { //string converter = "{0}"; var parameters = new List<object>(); switch (method.Name) { case "ToDateTime": //if (method.DeclaringType != typeof(Convert) || argsExp.Count != 1) //{ // throw new Exception("不支持"); //} Token = (Token)args[0]; parameters.AddRange(args.Skip(1)); //converter = Token.Column.Converter; //if (string.IsNullOrWhiteSpace(converter)) //{ // converter = "{0}"; //} //switch (Token.Type) //{ // case TokenType.Column: // converter = string.Format(converter, "CONVERT(DATETIME,{0},211)"); // Token.Column.Converter = converter; // break; // default: // throw new Exception(); //} break; case "Contains": Token = (Token)args[1]; //var list = ((Token)args[0]).Object as IList<int>; parameters.Add(args[0].Object); parameters.AddRange(args.Skip(2).Where(x => x.Type == TokenType.Object).Select(x => x.Object)); //if (method.DeclaringType != typeof(Enumerable)) //{ // throw new Exception("不支持"); //} //converter = string.Format(converter, "{0} in (" + string.Join(",", list) + ")"); //Token.Column.Converter = converter; break; default: throw new Exception(); } var converter = new ColumnConverter(method, parameters); Token.Column.Converters.Push(converter); } else { Token = Token.Create(node.Method.Invoke(null, args.Select(x => x.Object).ToArray())); } } else { var body = new MemberExpressionVisitor(Context); body.Visit(node.Object); if (body.Token.Type == TokenType.Column && !_isColumn) { //实例对象是列,参数不是列 Token = body.Token; //string converter = Token.Column.Converter; //if (string.IsNullOrWhiteSpace(converter)) //{ // converter = "{0}"; //} var method = node.Method; var argObjects = args.Select(x => x.Object); //Token.Column.ConverterParameters.AddRange(argObjects); Token.Column.Converters.Push(new ColumnConverter(method, argObjects.ToList(), true)); //switch (method.Name) //{ // case "ToDateTime": // if (method.DeclaringType != typeof(Convert) || argsExp.Count != 1) // { // throw new Exception("不支持"); // } // converter = string.Format(converter, "CONVERT(DATETIME,{0},211)"); // break; // case "Substring": // if (method.DeclaringType != typeof(string)) // { // throw new Exception("不支持"); // } // if (argsExp.Count == 1) // { // //SubString(startIndex) // ExpressionVisitorBase visitor = new PropertyFieldExpressionVisitor(Context); // visitor.Visit(argsExp[0]); // if (visitor.Token.Type != TokenType.Object) // { // throw new Exception("不支持"); // } // converter = string.Format(converter, "SUBSTRING({0}," + (Convert.ToInt32(argObjects[0]) + 1) + ",LEN({0})+1-" + Convert.ToInt32(visitor.Token.Object) + ")"); // } // else if (argsExp.Count == 2) // { // //SubString(startIndex,length) // ExpressionVisitorBase startVisitor = new PropertyFieldExpressionVisitor(Context); // startVisitor.Visit(argsExp[0]); // if (startVisitor.Token.Type != TokenType.Object) // { // throw new Exception("不支持"); // } // ExpressionVisitorBase lenVistior = new PropertyFieldExpressionVisitor(Context); // lenVistior.Visit(argsExp[1]); // if (lenVistior.Token.Type != TokenType.Object) // { // throw new Exception("不支持"); // } // converter = string.Format(converter, "SUBSTRING({0}," + (Convert.ToInt32(startVisitor.Token.Object) + 1) + "," + Convert.ToInt32(lenVistior.Token.Object) + ")"); // } // else // { // throw new Exception("不支持"); // } // break; // case "Contains": // if (method.DeclaringType == typeof(string)) // { // converter = string.Format(converter, "CHARINDEX(@param1,{0})>0"); // Token.Column.ConverterParameters.AddRange(argObjects); // } // else // { // throw new Exception("不支持"); // } // break; // case "StartsWith": // if (method.DeclaringType == typeof(string)) // { // converter = string.Format(converter, "CHARINDEX(@param1,{0})=1"); // Token.Column.ConverterParameters.AddRange(argObjects); // } // else // { // throw new Exception("不支持"); // } // break; // case "AddDays": // if (method.DeclaringType == typeof(DateTime)) // { // converter = string.Format(converter, "DATEADD(DAY,@param1,{0})"); // Token.Column.ConverterParameters.AddRange(argObjects); // } // else // { // throw new Exception("不支持"); // } // break; // case "AddHours": // if (method.DeclaringType == typeof(DateTime)) // { // converter = string.Format(converter, "DATEADD(HOUR,@param1,{0})"); // Token.Column.ConverterParameters.AddRange(argObjects); // } // else // { // throw new Exception("不支持"); // } // break; // case "AddMilliseconds": // if (method.DeclaringType == typeof(DateTime)) // { // converter = string.Format(converter, "DATEADD(MILLISECOND,@param1,{0})"); // Token.Column.ConverterParameters.AddRange(argObjects); // } // else // { // throw new Exception("不支持"); // } // break; // case "AddMinutes": // if (method.DeclaringType == typeof(DateTime)) // { // converter = string.Format(converter, "DATEADD(MINUTE,@param1,{0})"); // Token.Column.ConverterParameters.AddRange(argObjects); // } // else // { // throw new Exception("不支持"); // } // break; // case "AddMonths": // if (method.DeclaringType == typeof(DateTime)) // { // converter = string.Format(converter, "DATEADD(MONTH,@param1,{0})"); // Token.Column.ConverterParameters.AddRange(argObjects); // } // else // { // throw new Exception("不支持"); // } // break; // case "AddSeconds": // if (method.DeclaringType == typeof(DateTime)) // { // converter = string.Format(converter, "DATEADD(SECOND,@param1,{0})"); // Token.Column.ConverterParameters.AddRange(argObjects); // } // else // { // throw new Exception("不支持"); // } // break; // case "AddYears": // if (method.DeclaringType == typeof(DateTime)) // { // converter = string.Format(converter, "DATEADD(YEAR,@param1,{0})"); // Token.Column.ConverterParameters.AddRange(argObjects); // } // else // { // throw new Exception("不支持"); // } // break; // default: // throw new Exception(); //} //Token.Column.Converter = converter; } else if (body.Token.Type == TokenType.Object && !_isColumn) { Token = Token.Create(node.Method.Invoke(body.Token.Object, args.Select(x => x.Object).ToArray())); } else if (body.Token.Type == TokenType.Object && _isColumn) { Token = args[0]; var parameters = new List<object>(); parameters.Add(body.Token.Object); parameters.AddRange(args.Skip(1)); Token.Column.Converters.Push(new ColumnConverter(node.Method, parameters, false)); //string converter = Token.Column.Converter; //if (string.IsNullOrWhiteSpace(converter)) //{ // converter = "{0}"; //} //var method = node.Method; //switch (method.Name) //{ // case "Contains": // if (method.DeclaringType == typeof(string)) // { // converter = string.Format(converter, "CHARINDEX({0},@param1)>0"); // } // else // { // throw new Exception("不支持"); // } // break; // case "StartsWith": // if (method.DeclaringType == typeof(string)) // { // converter = string.Format(converter, "CHARINDEX(@param1,{0})>0"); // } // else // { // throw new Exception("不支持"); // } // break; // case "AddDays": // if (method.DeclaringType == typeof(DateTime)) // { // converter = string.Format(converter, "DATEADD(DAY,{0},@param1)"); // } // else // { // throw new Exception("不支持"); // } // break; // case "AddHours": // if (method.DeclaringType == typeof(DateTime)) // { // converter = string.Format(converter, "DATEADD(HOUR,{0},@param1)"); // } // else // { // throw new Exception("不支持"); // } // break; // case "AddMilliseconds": // if (method.DeclaringType == typeof(DateTime)) // { // converter = string.Format(converter, "DATEADD(MILLISECOND,{0},@param1)"); // } // else // { // throw new Exception("不支持"); // } // break; // case "AddMinutes": // if (method.DeclaringType == typeof(DateTime)) // { // converter = string.Format(converter, "DATEADD(MINUTE,{0},@param1)"); // } // else // { // throw new Exception("不支持"); // } // break; // case "AddMonths": // if (method.DeclaringType == typeof(DateTime)) // { // converter = string.Format(converter, "DATEADD(MONTH,{0},@param1)"); // } // else // { // throw new Exception("不支持"); // } // break; // case "AddSeconds": // if (method.DeclaringType == typeof(DateTime)) // { // converter = string.Format(converter, "DATEADD(SECOND,{0},@param1)"); // } // else // { // throw new Exception("不支持"); // } // break; // case "AddYears": // if (method.DeclaringType == typeof(DateTime)) // { // converter = string.Format(converter, "DATEADD(YEAR,{0},@param1)"); // } // else // { // throw new Exception("不支持"); // } // break; // default: // throw new Exception("不支持"); //} //Token.Column.Converter = converter; //Token.Column.ConverterParameters.Add(body.Token.Object); } else { throw new Exception(); } } return node; }
protected override Expression VisitMember(MemberExpression node) { if (node.Expression == null) { //静态属性访问,已到根节点 var value = GetValue(node, null); while (_memberInfos.Count > 0) { value = GetValue((MemberExpression)_memberInfos.Pop(), value); } Token = Token.Create(value); return(node); } if (node.Member.DeclaringType == typeof(TimeSpan)) { //var unit = string.Empty; //switch (node.Member.Name) //{ // case "TotalDays": // unit = "DAY"; // break; // case "TotalHours": // unit = "HOUR"; // break; // case "TotalMilliseconds": // unit = "MILLISECOND"; // break; // case "TotalMinutes": // unit = "MINUTE"; // break; // case "TotalSeconds": // unit = "SECOND"; // break; // default: // throw new Exception(); //} if (node.Expression.NodeType == ExpressionType.Subtract) { var binaryExp = (BinaryExpression)node.Expression; var left = binaryExp.Left; var right = binaryExp.Right; var leftVisitor = new MemberExpressionVisitor(Context); leftVisitor.Visit(left); var rightVisitor = new MemberExpressionVisitor(Context); rightVisitor.Visit(right); if (leftVisitor.Token.Type == TokenType.Column && rightVisitor.Token.Type == TokenType.Object) { var rightObject = (DateTime)rightVisitor.Token.Object; //leftVisitor.Token.Column.Converter = "DATEDIFF(" + unit + ",@param1,{0})"; //leftVisitor.Token.Column.ConverterParameters.Add(rightObject); Token = leftVisitor.Token; Token.Column.Converters.Push(new ColumnConverter(node.Member, new List <object>() { rightObject }, true)); //Token.Column.Converters.Push(node.Member); } else if (leftVisitor.Token.Type == TokenType.Object && rightVisitor.Token.Type == TokenType.Column) { var leftObject = (DateTime)leftVisitor.Token.Object; //leftVisitor.Token.Column.Converter = "DATEDIFF(" + unit + ",@param1,{0})"; //leftVisitor.Token.Column.ConverterParameters.Add(rightObject); Token = rightVisitor.Token; Token.Column.Converters.Push(new ColumnConverter(node.Member, new List <object>() { leftObject }, false)); } else { throw new Exception(); } } else { throw new Exception(); } return(node); } _memberInfos.Push(node); return(base.VisitMember(node)); }
Token ParseMathBinary(BinaryExpression node) { ExpressionVisitorBase leftVisitor, rightVisitor; if (node.Left is BinaryExpression) { leftVisitor = new BinaryExpressionVisitor(Context); } else { leftVisitor = new MemberExpressionVisitor(Context); } leftVisitor.Visit(node.Left); var leftResult = leftVisitor.Token; if (node.Right is BinaryExpression) { rightVisitor = new BinaryExpressionVisitor(Context); } else { rightVisitor = new MemberExpressionVisitor(Context); } rightVisitor.Visit(node.Right); var rightResult = rightVisitor.Token; if (leftResult.Type == TokenType.Object && rightResult.Type == TokenType.Object) { if (leftResult.Object == null && rightResult.Object == null) { return Token.Create(true); } if (leftResult == null || rightResult == null) { return Token.Create(false); } if (leftResult.Type == TokenType.Object) { if (leftResult.Object is string || leftResult.Object is bool || leftResult.Object is bool?) { return Token.Create(leftResult.Equals(rightResult)); } #region 比大小 if (leftResult.Object is DateTime || leftResult.Object is DateTime?) { var left = Convert.ToDateTime(leftResult.Object); var right = Convert.ToDateTime(rightResult.Object); switch (node.NodeType) { case ExpressionType.LessThan: return Token.Create(left < right); case ExpressionType.LessThanOrEqual: return Token.Create(left <= right); case ExpressionType.Equal: return Token.Create(left = right); case ExpressionType.GreaterThan: return Token.Create(left > right); case ExpressionType.GreaterThanOrEqual: return Token.Create(left >= right); default: throw new Exception(); } } else if (leftResult.Object is int || leftResult.Object is int?) { var left = Convert.ToInt32(leftResult.Object); var right = Convert.ToInt32(rightResult.Object); switch (node.NodeType) { case ExpressionType.LessThan: return Token.Create(left < right); case ExpressionType.LessThanOrEqual: return Token.Create(left <= right); case ExpressionType.Equal: return Token.Create(left = right); case ExpressionType.GreaterThan: return Token.Create(left > right); case ExpressionType.GreaterThanOrEqual: return Token.Create(left >= right); default: throw new Exception(); } } else if (leftResult.Object is short || leftResult.Object is short?) { var left = Convert.ToInt16(leftResult.Object); var right = Convert.ToInt16(rightResult.Object); switch (node.NodeType) { case ExpressionType.LessThan: return Token.Create(left < right); case ExpressionType.LessThanOrEqual: return Token.Create(left <= right); case ExpressionType.Equal: return Token.Create(left = right); case ExpressionType.GreaterThan: return Token.Create(left > right); case ExpressionType.GreaterThanOrEqual: return Token.Create(left >= right); default: throw new Exception(); } } else if (leftResult.Object is long || leftResult.Object is long?) { var left = Convert.ToInt64(leftResult.Object); var right = Convert.ToInt64(rightResult.Object); switch (node.NodeType) { case ExpressionType.LessThan: return Token.Create(left < right); case ExpressionType.LessThanOrEqual: return Token.Create(left <= right); case ExpressionType.Equal: return Token.Create(left = right); case ExpressionType.GreaterThan: return Token.Create(left > right); case ExpressionType.GreaterThanOrEqual: return Token.Create(left >= right); default: throw new Exception(); } } else { return Token.Create(leftResult.Object == rightResult.Object); } #endregion } else { throw new Exception(); } } else if (leftResult.Type == TokenType.Column && rightResult.Type == TokenType.Object) { var condition = new Condition(); condition.Left = leftResult; condition.CompareType = SelectMathCompareType(node.NodeType); condition.Right = Token.Create(rightResult.Object); return Token.Create(condition); } else if (leftResult.Type == TokenType.Condition && rightResult.Type == TokenType.Object) { var condition = new Condition(); condition.Left = leftResult; condition.CompareType = SelectMathCompareType(node.NodeType); condition.Right = Token.Create(rightResult.Object); return Token.Create(condition); } else { throw new Exception(); } throw new Exception(); }
Token ParseNotExpression(UnaryExpression unaryExpression) { var operand = unaryExpression.Operand; if (operand is MemberExpression) { var visitor = new MemberExpressionVisitor(Context); visitor.Visit(operand); switch (visitor.Token.Type) { case TokenType.Object: if (visitor.Token.IsBool()) { return Token.Create(!((bool)visitor.Token.Object)); } else { throw new Exception("不支持"); } case TokenType.Column: if (operand.Type == typeof(bool) || operand.Type == typeof(bool?)) { return Token.Create(new Condition() { CompareType = CompareType.Equal, Left = Token.Create(1), Right = Token.Create(1) }); } return Token.Create(new Condition() { Left = visitor.Token, CompareType = CompareType.Not }); default: throw new Exception(); } } else if (operand is MethodCallExpression) { var visitor = new MethodCallExpressionVisitor(Context); visitor.Visit(operand); var token = visitor.Token; switch (token.Type) { case TokenType.Column: return Token.Create(new Condition() { Left = token, CompareType = CompareType.Not }); case TokenType.Condition: return Token.Create(new Condition() { Left = Token.Create(token.Condition), CompareType = CompareType.Not }); case TokenType.Object: return Token.Create(!((bool)token.Object)); default: throw new Exception(); } } else { throw new Exception("不支持"); } throw new Exception(); }
protected override Expression VisitNew(NewExpression node) { for (int i = 0; i < node.Arguments.Count; i++) { var visitor = new MemberExpressionVisitor(Context); var arg = node.Arguments[i]; var member = node.Members[i]; visitor.Visit(arg); visitor.SelectedColumn.Alias = member.Name; Columns.Add(visitor.SelectedColumn); Context.Columns.Add(member.Name, visitor.SelectedColumn); } return node; }
protected override Expression VisitMember(MemberExpression node) { if (node.Expression == null) { //静态属性访问,已到根节点 var value = GetValue(node, null); while (_memberInfos.Count > 0) { value = GetValue((MemberExpression)_memberInfos.Pop(), value); } Token = Token.Create(value); return node; } if (node.Member.DeclaringType == typeof(TimeSpan)) { //var unit = string.Empty; //switch (node.Member.Name) //{ // case "TotalDays": // unit = "DAY"; // break; // case "TotalHours": // unit = "HOUR"; // break; // case "TotalMilliseconds": // unit = "MILLISECOND"; // break; // case "TotalMinutes": // unit = "MINUTE"; // break; // case "TotalSeconds": // unit = "SECOND"; // break; // default: // throw new Exception(); //} if (node.Expression.NodeType == ExpressionType.Subtract) { var binaryExp = (BinaryExpression)node.Expression; var left = binaryExp.Left; var right = binaryExp.Right; var leftVisitor = new MemberExpressionVisitor(Context); leftVisitor.Visit(left); var rightVisitor = new MemberExpressionVisitor(Context); rightVisitor.Visit(right); if (leftVisitor.Token.Type == TokenType.Column && rightVisitor.Token.Type == TokenType.Object) { var rightObject = (DateTime)rightVisitor.Token.Object; //leftVisitor.Token.Column.Converter = "DATEDIFF(" + unit + ",@param1,{0})"; //leftVisitor.Token.Column.ConverterParameters.Add(rightObject); Token = leftVisitor.Token; Token.Column.Converters.Push(new ColumnConverter(node.Member, new List<object>() { rightObject }, true)); //Token.Column.Converters.Push(node.Member); } else if (leftVisitor.Token.Type == TokenType.Object && rightVisitor.Token.Type == TokenType.Column) { var leftObject = (DateTime)leftVisitor.Token.Object; //leftVisitor.Token.Column.Converter = "DATEDIFF(" + unit + ",@param1,{0})"; //leftVisitor.Token.Column.ConverterParameters.Add(rightObject); Token = rightVisitor.Token; Token.Column.Converters.Push(new ColumnConverter(node.Member, new List<object>() { leftObject }, false)); } else { throw new Exception(); } } else { throw new Exception(); } return node; } _memberInfos.Push(node); return base.VisitMember(node); }