protected override Expression VisitBinary(BinaryExpression node) { if (node.NodeType == ExpressionType.AndAlso) { this.Visit((BinaryExpression)node.Left); this.Visit((BinaryExpression)node.Right); return(node); } else if (node.NodeType == ExpressionType.OrElse) { var filter = new Or { Operator = node.NodeType.ToString() }; var whereVisitor = new WhereClauseVisitor(); whereVisitor.lambdaExpression = this.lambdaExpression; whereVisitor.Visit(node.Left); whereVisitor.Visit(node.Right); filter.Clauses = whereVisitor.Filters; filter.Expression = Expression.Lambda(node, parameter); _filters.Add(filter); return(node); } else { var filter = new Where(); var member = node.Left as MemberExpression; if (member == null) { var unaryMember = node.Left as UnaryExpression; if (unaryMember != null) { member = unaryMember.Operand as MemberExpression; } } if (member != null) { filter.PropertyName = member.Member.Name; } filter.Expression = Expression.Lambda(node, parameter); filter.Operator = node.NodeType.ToString(); var valueNode = parameter != null && parameter == (node.Right as MemberExpression)?.Expression ? node.Left : node.Right; filter.Value = GetValueFromExpression(valueNode); _filters.Add(filter); return(node); } }
// override ExpressionVisitor method protected override Expression VisitMethodCall(MethodCallExpression m) { if ((m.Method.DeclaringType == typeof(Queryable)) || (m.Method.DeclaringType == typeof(Enumerable))) { if (m.Method.Name.Equals("Skip")) { Visit(m.Arguments[0]); var countExpression = (ConstantExpression)(m.Arguments[1]); QueryInfo.Skip = ((int)countExpression.Value); return(m); } else if (m.Method.Name.Equals("Take")) { Visit(m.Arguments[0]); var countExpression = (ConstantExpression)(m.Arguments[1]); QueryInfo.Take = ((int)countExpression.Value); return(m); } else if (m.Method.Name.Equals("Select")) { MethodCallExpression call = m; LambdaExpression lambda = (LambdaExpression)ExpressionUtils.RemoveQuotes(call.Arguments[1]); Expression body = ExpressionUtils.RemoveQuotes(lambda.Body); Select = new ExpressionUtils.SelectCallMatch { MethodCall = call, Source = call.Arguments[0], Lambda = lambda, LambdaBody = body }; } else if (m.Method.Name.Equals("OrderByDescending")) { MethodCallExpression call = m; var lambda = (LambdaExpression)ExpressionUtils.RemoveQuotes(call.Arguments[1]); var lambdaBody = (MemberExpression)ExpressionUtils.RemoveQuotes(lambda.Body); QueryInfo.OrderBy = new OrderBy(lambdaBody.Member.Name, OrderBy.OrderByDirection.Desc); } else if (m.Method.Name.Equals("OrderBy")) { MethodCallExpression call = m; var lambda = (LambdaExpression)ExpressionUtils.RemoveQuotes(call.Arguments[1]); var lambdaBody = (MemberExpression)ExpressionUtils.RemoveQuotes(lambda.Body); QueryInfo.OrderBy = new OrderBy(lambdaBody.Member.Name, OrderBy.OrderByDirection.Asc); } else if (m.Method.Name.Equals("Where")) { MethodCallExpression call = m; var whereClause = call.Arguments[1]; var whereClauseVisitor = new WhereClauseVisitor(); whereClauseVisitor.Visit(whereClause); QueryInfo.Clauses = QueryInfo.Clauses.Concat((whereClauseVisitor.Filters)).ToArray(); } else if (m.Method.Name.Equals("GroupBy")) { MethodCallExpression call = m; LambdaExpression keyExpression = (LambdaExpression)ExpressionUtils.RemoveQuotes(call.Arguments[1]); Expression body = ExpressionUtils.RemoveQuotes(keyExpression.Body); QueryInfo.GroupBy = new GroupBy() { KeySelector = new ExpressionUtils.SelectCallMatch { MethodCall = call, Source = call.Arguments[0], Lambda = keyExpression, LambdaBody = body } }; } else if (m.Method.Name.Equals("Single")) { QueryInfo.ResultType = new Single(); } else if (m.Method.Name.Equals("Count")) { QueryInfo.ResultType = new Count(); } else { throw new NotImplementedException($"Operator {m.Method.Name} not supported. Please update the project at https://github.com/mcintyre321/LinqToAnything/blob/master/LinqToAnything/QueryVisitor.cs"); } } return(m); }