protected override Expression VisitMethodCall(MethodCallExpression methodExp) { switch (methodExp.Method.Name) { case "Contains": if (methodExp.Method.DeclaringType == typeof(string)) { this.Visit(methodExp.Object); SqlBuilder.AppendFormat(SqlDialect.Contains(), TranslateClause(methodExp.Arguments[0])); return(methodExp); } else { Expression mex; if (methodExp.Object != null) { this.Visit(methodExp.Arguments[0]); SqlBuilder.Append(" IN ("); mex = methodExp.Object; } else { this.Visit(methodExp.Arguments[1]); SqlBuilder.Append(" IN ("); mex = methodExp.Arguments[0]; } if (mex.NodeType == ExpressionType.Call && mex is MethodCallExpression && ((MethodCallExpression)mex).Method.DeclaringType == typeof(SubQuery)) { this.Visit(mex); } else { IEnumerable result = Expression.Lambda(mex).Compile().DynamicInvoke() as IEnumerable; int length = 0; foreach (var v in result) { length++; this.Visit(Expression.Constant(v)); SqlBuilder.Append(","); } if (length == 0) { SqlBuilder.Append("NULL,"); } SqlBuilder.Remove(SqlBuilder.Length - 1, 1); } SqlBuilder.Append(")"); return(methodExp); } case "ToUpper": SqlBuilder.Append(" UPPER("); this.Visit(methodExp.Object); SqlBuilder.Append(")"); return(methodExp); case "ToLower": SqlBuilder.Append(" LOWER("); this.Visit(methodExp.Object); SqlBuilder.Append(")"); return(methodExp); case "CompareTo": IsPreTreatBinary = true; this.Visit(methodExp.Object); SqlBuilder.Append("{0}"); this.Visit(methodExp.Arguments[0]); return(methodExp); case "Equals": this.Visit(methodExp.Object); SqlBuilder.Append("="); this.Visit(methodExp.Arguments[0]); return(methodExp); case "IndexOf": SqlBuilder.AppendFormat(SqlDialect.IndexOf(), TranslateClause(methodExp.Arguments[0]), TranslateClause(methodExp.Object)); return(methodExp); case "IsNullOrEmpty": string template = " ({0} IS NULL OR {0}='') "; string[] sections = template.Split(new string[] { "{0}" }, StringSplitOptions.None); for (int i = 0; i < sections.Length - 1; i++) { if (i == 0) { SqlBuilder.Append(sections[i]); } this.Visit(methodExp.Arguments[0]); SqlBuilder.Append(sections[i + 1]); } return(methodExp); case "ToString": //Convert.ToString() if (methodExp.Method.DeclaringType == typeof(System.Convert)) { MemberTypeVisitor mtVisitor = new MemberTypeVisitor(); MemberType = mtVisitor.Translate(methodExp.Arguments[0]); if (MemberType != null) { SqlBuilder.AppendFormat(SqlDialect.ToChar(), TranslateClause(methodExp.Arguments[0])); return(methodExp); } } else if (methodExp.Method.DeclaringType == typeof(System.Object)) { MemberTypeVisitor mtVisitor = new MemberTypeVisitor(); MemberType = mtVisitor.Translate(methodExp.Object); if (MemberType != null) { SqlBuilder.AppendFormat(SqlDialect.ToChar(), TranslateClause(methodExp.Object)); return(methodExp); } } else if (methodExp.Method.DeclaringType == typeof(Nullable <DateTime>) || methodExp.Method.DeclaringType == typeof(DateTime)) { if (methodExp.Arguments[0] is ConstantExpression) { MemberTypeVisitor mtVisitor = new MemberTypeVisitor(); MemberType = mtVisitor.Translate(methodExp.Object); if (MemberType != null) { string timeFormat = ((ConstantExpression)methodExp.Arguments[0]).Value as string; string clause = TranslateClause(methodExp.Object); //非列就转向了 if (string.IsNullOrEmpty(clause)) { goto default; } SqlBuilder.AppendFormat("(" + SqlDialect.ParseTimeFormat(timeFormat) + ")", clause); return(methodExp); } } } goto default; case "ToInt32": //Convert.ToInt32() if (methodExp.Method.DeclaringType == typeof(System.Convert)) { MemberTypeVisitor mtVisitor = new MemberTypeVisitor(); MemberType = mtVisitor.Translate(methodExp.Arguments[0]); if (MemberType != null) { SqlBuilder.AppendFormat(SqlDialect.ToNumber(), TranslateClause(methodExp.Arguments[0])); return(methodExp); } } goto default; case "ToDateTime": if (methodExp.Method.DeclaringType == typeof(System.Convert)) { MemberTypeVisitor mtVisitor = new MemberTypeVisitor(); MemberType = mtVisitor.Translate(methodExp.Arguments[0]); if (MemberType == typeof(Nullable <DateTime>) || MemberType == typeof(DateTime)) { this.Visit(methodExp.Arguments[0]); return(methodExp); } else if (MemberType == typeof(string)) { SqlBuilder.AppendFormat(SqlDialect.ToDateTime(), TranslateClause(methodExp.Arguments[0])); return(methodExp); } } goto default; case "StartsWith": this.Visit(methodExp.Object); SqlBuilder.AppendFormat(SqlDialect.StartsWith(), TranslateClause(methodExp.Arguments[0])); return(methodExp); case "EndsWith": this.Visit(methodExp.Object); SqlBuilder.AppendFormat(SqlDialect.EndsWith(), TranslateClause(methodExp.Arguments[0])); return(methodExp); case "TrimStart": SqlBuilder.Append(" LTRIM("); this.Visit(methodExp.Object); SqlBuilder.Append(")"); return(methodExp); case "TrimEnd": SqlBuilder.Append(" RTRIM("); this.Visit(methodExp.Object); SqlBuilder.Append(")"); return(methodExp); case "Trim": SqlBuilder.Append(" RTRIM(LTRIM("); this.Visit(methodExp.Object); SqlBuilder.Append("))"); return(methodExp); case "Count": if (methodExp.Method.DeclaringType == typeof(SqlFunctions)) { SqlBuilder.AppendFormat("COUNT({0})", TranslateClause(methodExp.Arguments[0])); return(methodExp); } goto default; case "CountDistinct": if (methodExp.Method.DeclaringType == typeof(SqlFunctions)) { SqlBuilder.AppendFormat("COUNT(DISTINCT {0})", TranslateClause(methodExp.Arguments[0])); return(methodExp); } goto default; case "Max": case "Min": case "Avg": if (methodExp.Method.DeclaringType == typeof(SqlFunctions)) { SqlBuilder.AppendFormat("{0}({1})", methodExp.Method.Name, TranslateClause(methodExp.Arguments[0])); return(methodExp); } goto default; case "GetSingle": if (methodExp.Method.DeclaringType == typeof(SubQuery)) { Expression opd1 = methodExp.Arguments[0]; Expression opd2 = methodExp.Arguments[1]; if (methodExp.Arguments[0].NodeType == ExpressionType.Quote) { opd1 = ((UnaryExpression)(methodExp.Arguments[0])).Operand; } if (methodExp.Arguments[1].NodeType == ExpressionType.Quote) { opd2 = ((UnaryExpression)(methodExp.Arguments[1])).Operand; } if (WithAlias) { SqlBuilder.AppendFormat("(SELECT {0} FROM {1} AS {3} WHERE {2})", TranslateClause(((LambdaExpression)opd2).Body), GetTableName(((LambdaExpression)opd1).Parameters[0].Type), TranslateClause(((LambdaExpression)opd1).Body), ((LambdaExpression)opd1).Parameters[0].Name); } else { SqlBuilder.AppendFormat("(SELECT {0} FROM {1} WHERE {2})", TranslateClause(((LambdaExpression)opd2).Body), GetTableName(((LambdaExpression)opd1).Parameters[0].Type), TranslateClause(((LambdaExpression)opd1).Body)); } return(methodExp); } goto default; case "GetList": if (methodExp.Method.DeclaringType == typeof(SubQuery)) { Expression opd1 = methodExp.Arguments[0]; Expression opd2 = methodExp.Arguments[1]; if (methodExp.Arguments[0].NodeType == ExpressionType.Quote) { opd1 = ((UnaryExpression)(methodExp.Arguments[0])).Operand; } if (methodExp.Arguments[1].NodeType == ExpressionType.Quote) { opd2 = ((UnaryExpression)(methodExp.Arguments[1])).Operand; } if (WithAlias) { SqlBuilder.AppendFormat("SELECT {0} FROM {1} AS {3} WHERE {2}", TranslateClause(((LambdaExpression)opd2).Body), GetTableName(((LambdaExpression)opd1).Parameters[0].Type), TranslateClause(((LambdaExpression)opd1).Body), ((LambdaExpression)opd1).Parameters[0].Name); } else { SqlBuilder.AppendFormat("SELECT {0} FROM {1} WHERE {2}", TranslateClause(((LambdaExpression)opd2).Body), GetTableName(((LambdaExpression)opd1).Parameters[0].Type), TranslateClause(((LambdaExpression)opd1).Body)); } return(methodExp); } goto default; default: try { object result = Expression.Lambda(methodExp).Compile().DynamicInvoke(); var r = Expression.Constant(result, methodExp.Method.ReturnType); this.Visit(r); return(r); } catch { if (methodExp.Object != null) { Expression obj = this.Visit(methodExp.Object); return(obj); } else { Expression obj = this.Visit(methodExp.Arguments[0]); return(obj); } } throw new NotSupportedException(string.Format("lambda表达式不支持使用此'{0}'方法,请自行扩展", methodExp.Method.Name)); } }