//-------------------------------------------------------------------------------------------------------------------------------------------------- #region Private methods //-------------------------------------------------------------------------------------------------------------------------------------------------- private Expression JoinMethod(MethodCallExpression expression) { // first argument is another join or method call if (expression.Arguments[0] is MethodCallExpression) { VisitMethodCall((MethodCallExpression)expression.Arguments[0]); } var joinFromType = ((LambdaExpression)((UnaryExpression)expression.Arguments[4]).Operand).Parameters[0].Type; // from type if generic, possbily another join if (joinFromType.IsGenericType) { joinFromType = joinFromType.GenericTypeArguments[1]; } var joinToType = ((LambdaExpression)((UnaryExpression)expression.Arguments[4]).Operand).Parameters[1].Type; EntityTableCacheHelper.ToEntityTable(joinFromType); var joinToTable = EntityTableCacheHelper.ToEntityTable(joinToType); var primaryJoinColumn = _serverWriter.GetPropertyNameWithIdentifierFromExpression(expression.Arguments[2]); var secondaryJoinColumn = _serverWriter.GetPropertyNameWithIdentifierFromExpression(expression.Arguments[3]); _serverWriter.WriteJoin(joinToTable.Name, joinToTable.Identifier, primaryJoinColumn, secondaryJoinColumn); return(expression); }
/// <summary> /// Visits the children of the <see cref="T:System.Linq.Expressions.MethodCallExpression"/>. /// </summary> /// <returns> /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. /// </returns> /// <param name="node">The expression to visit.</param> protected override Expression VisitMethodCall(MethodCallExpression node) { switch (node.Method.Name) { case MethodCall.EndsWith: case MethodCall.StartsWith: case MethodCall.Contains: // LIKE '(%)xyz(%)' // LIKE IN (x, y, s) return(LikeInMethod(node)); case MethodCall.IsNullOrEmpty: // ISNULL(x, '') (!)= '' if (IsNullMethod(node)) { return(node); } break; case MethodCall.Join: return(JoinMethod(node)); case MethodCall.Skip: _serverWriter.SkipCount = (int)node.Arguments[1].GetValueFromExpression(); return(Visit(node.Arguments[0])); case MethodCall.Take: // TOP(..) _serverWriter.TopCount = (int)node.Arguments[1].GetValueFromExpression(); return(Visit(node.Arguments[0])); // return node; case MethodCall.Single: case MethodCall.First: case MethodCall.FirstOrDefault: // TOP(1) _serverWriter.TopCount = 1; return(Visit(node.Arguments[node.Arguments.Count - 1])); case MethodCall.Distinct: // DISTINCT _serverWriter.IsDistinct = true; return(node); case MethodCall.Count: case MethodCall.LongCount: _serverWriter.IsCount = true; return(Visit(node.Arguments[node.Arguments.Count - 1])); case MethodCall.OrderBy: case MethodCall.ThenBy: case MethodCall.OrderByDescending: case MethodCall.ThenByDescending: // ORDER BY ... _serverWriter.WriteOrder(_serverWriter.GetPropertyNameWithIdentifierFromExpression(node.Arguments[1]), node.Method.Name.Contains("Descending")); return(Visit(node.Arguments[0])); case MethodCall.Select: var type = ((LambdaExpression)((UnaryExpression)node.Arguments[1]).Operand).Body.Type; EntityTableCacheHelper.ToEntityTable(type); _serverWriter.SelectType = type; return(base.VisitMethodCall(node)); } return(base.VisitMethodCall(node)); }