private SqlNode VisitSequenceOperatorCall()

in System.Data.Linq/SqlClient/Query/QueryConverter.cs [2031:2317]


        private SqlNode VisitSequenceOperatorCall(MethodCallExpression mc) {
            Type declType = mc.Method.DeclaringType;
            bool isSupportedSequenceOperator = false;
            if (IsSequenceOperatorCall(mc)) {
                switch (mc.Method.Name) {
                    case "Select":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 2 &&
                            this.IsLambda(mc.Arguments[1]) && this.GetLambda(mc.Arguments[1]).Parameters.Count == 1) {
                            return this.VisitSelect(mc.Arguments[0], this.GetLambda(mc.Arguments[1]));
                        }
                        break;
                    case "SelectMany":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 2 &&
                            this.IsLambda(mc.Arguments[1]) && this.GetLambda(mc.Arguments[1]).Parameters.Count == 1) {
                            return this.VisitSelectMany(mc.Arguments[0], this.GetLambda(mc.Arguments[1]), null);
                        }
                        else if (mc.Arguments.Count == 3 &&
                            this.IsLambda(mc.Arguments[1]) && this.GetLambda(mc.Arguments[1]).Parameters.Count == 1 &&
                            this.IsLambda(mc.Arguments[2]) && this.GetLambda(mc.Arguments[2]).Parameters.Count == 2) {
                            return this.VisitSelectMany(mc.Arguments[0], this.GetLambda(mc.Arguments[1]), this.GetLambda(mc.Arguments[2]));
                        }
                        break;
                    case "Join":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 5 &&
                            this.IsLambda(mc.Arguments[2]) && this.GetLambda(mc.Arguments[2]).Parameters.Count == 1 &&
                            this.IsLambda(mc.Arguments[3]) && this.GetLambda(mc.Arguments[3]).Parameters.Count == 1 &&
                            this.IsLambda(mc.Arguments[4]) && this.GetLambda(mc.Arguments[4]).Parameters.Count == 2) {
                            return this.VisitJoin(mc.Arguments[0], mc.Arguments[1], this.GetLambda(mc.Arguments[2]), this.GetLambda(mc.Arguments[3]), this.GetLambda(mc.Arguments[4]));
                        }
                        break;
                    case "GroupJoin":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 5 &&
                            this.IsLambda(mc.Arguments[2]) && this.GetLambda(mc.Arguments[2]).Parameters.Count == 1 &&
                            this.IsLambda(mc.Arguments[3]) && this.GetLambda(mc.Arguments[3]).Parameters.Count == 1 &&
                            this.IsLambda(mc.Arguments[4]) && this.GetLambda(mc.Arguments[4]).Parameters.Count == 2) {
                            return this.VisitGroupJoin(mc.Arguments[0], mc.Arguments[1], this.GetLambda(mc.Arguments[2]), this.GetLambda(mc.Arguments[3]), this.GetLambda(mc.Arguments[4]));
                        }
                        break;
                    case "DefaultIfEmpty":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 1) {
                            return this.VisitDefaultIfEmpty(mc.Arguments[0]);
                        }
                        break;
                    case "OfType":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 1) {
                            Type ofType = mc.Method.GetGenericArguments()[0];
                            return this.VisitOfType(mc.Arguments[0], ofType);
                        }
                        break;
                    case "Cast":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 1) {
                            Type type = mc.Method.GetGenericArguments()[0];
                            return this.VisitSequenceCast(mc.Arguments[0], type);
                        }
                        break;
                    case "Where":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 2 &&
                            this.IsLambda(mc.Arguments[1]) && this.GetLambda(mc.Arguments[1]).Parameters.Count == 1) {
                            return this.VisitWhere(mc.Arguments[0], this.GetLambda(mc.Arguments[1]));
                        }
                        break;
                    case "First":
                    case "FirstOrDefault":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 1) {
                            return this.VisitFirst(mc.Arguments[0], null, true);
                        }
                        else if (mc.Arguments.Count == 2 &&
                            this.IsLambda(mc.Arguments[1]) && this.GetLambda(mc.Arguments[1]).Parameters.Count == 1) {
                            return this.VisitFirst(mc.Arguments[0], this.GetLambda(mc.Arguments[1]), true);
                        }
                        break;
                    case "Single":
                    case "SingleOrDefault":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 1) {
                            return this.VisitFirst(mc.Arguments[0], null, false);
                        }
                        else if (mc.Arguments.Count == 2 &&
                            this.IsLambda(mc.Arguments[1]) && this.GetLambda(mc.Arguments[1]).Parameters.Count == 1) {
                            return this.VisitFirst(mc.Arguments[0], this.GetLambda(mc.Arguments[1]), false);
                        }
                        break;
                    case "Distinct":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 1) {
                            return this.VisitDistinct(mc.Arguments[0]);
                        }
                        break;
                    case "Concat":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 2) {
                            return this.VisitConcat(mc.Arguments[0], mc.Arguments[1]);
                        }
                        break;
                    case "Union":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 2) {
                            return this.VisitUnion(mc.Arguments[0], mc.Arguments[1]);
                        }
                        break;
                    case "Intersect":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 2) {
                            return this.VisitIntersect(mc.Arguments[0], mc.Arguments[1]);
                        }
                        break;
                    case "Except":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 2) {
                            return this.VisitExcept(mc.Arguments[0], mc.Arguments[1]);
                        }
                        break;
                    case "Any":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 1) {
                            return this.VisitQuantifier(mc.Arguments[0], null, true);
                        }
                        else if (mc.Arguments.Count == 2 &&
                            this.IsLambda(mc.Arguments[1]) && this.GetLambda(mc.Arguments[1]).Parameters.Count == 1) {
                            return this.VisitQuantifier(mc.Arguments[0], this.GetLambda(mc.Arguments[1]), true);
                        }
                        break;
                    case "All":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 2 &&
                            this.IsLambda(mc.Arguments[1]) && this.GetLambda(mc.Arguments[1]).Parameters.Count == 1) {
                            return this.VisitQuantifier(mc.Arguments[0], this.GetLambda(mc.Arguments[1]), false);
                        }
                        break;
                    case "Count":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 1) {
                            return this.VisitAggregate(mc.Arguments[0], null, SqlNodeType.Count, mc.Type);
                        }
                        else if (mc.Arguments.Count == 2 &&
                            this.IsLambda(mc.Arguments[1]) && this.GetLambda(mc.Arguments[1]).Parameters.Count == 1) {
                            return this.VisitAggregate(mc.Arguments[0], this.GetLambda(mc.Arguments[1]), SqlNodeType.Count, mc.Type);
                        }
                        break;
                    case "LongCount":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 1) {
                            return this.VisitAggregate(mc.Arguments[0], null, SqlNodeType.LongCount, mc.Type);
                        }
                        else if (mc.Arguments.Count == 2 &&
                            this.IsLambda(mc.Arguments[1]) && this.GetLambda(mc.Arguments[1]).Parameters.Count == 1) {
                            return this.VisitAggregate(mc.Arguments[0], this.GetLambda(mc.Arguments[1]), SqlNodeType.LongCount, mc.Type);
                        }
                        break;
                    case "Sum":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 1) {
                            return this.VisitAggregate(mc.Arguments[0], null, SqlNodeType.Sum, mc.Type);
                        }
                        else if (mc.Arguments.Count == 2 &&
                            this.IsLambda(mc.Arguments[1]) && this.GetLambda(mc.Arguments[1]).Parameters.Count == 1) {
                            return this.VisitAggregate(mc.Arguments[0], this.GetLambda(mc.Arguments[1]), SqlNodeType.Sum, mc.Type);
                        }
                        break;
                    case "Min":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 1) {
                            return this.VisitAggregate(mc.Arguments[0], null, SqlNodeType.Min, mc.Type);
                        }
                        else if (mc.Arguments.Count == 2 &&
                            this.IsLambda(mc.Arguments[1]) && this.GetLambda(mc.Arguments[1]).Parameters.Count == 1) {
                            return this.VisitAggregate(mc.Arguments[0], this.GetLambda(mc.Arguments[1]), SqlNodeType.Min, mc.Type);
                        }
                        break;
                    case "Max":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 1) {
                            return this.VisitAggregate(mc.Arguments[0], null, SqlNodeType.Max, mc.Type);
                        }
                        else if (mc.Arguments.Count == 2 &&
                            this.IsLambda(mc.Arguments[1]) && this.GetLambda(mc.Arguments[1]).Parameters.Count == 1) {
                            return this.VisitAggregate(mc.Arguments[0], this.GetLambda(mc.Arguments[1]), SqlNodeType.Max, mc.Type);
                        }
                        break;
                    case "Average":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 1) {
                            return this.VisitAggregate(mc.Arguments[0], null, SqlNodeType.Avg, mc.Type);
                        }
                        else if (mc.Arguments.Count == 2 &&
                            this.IsLambda(mc.Arguments[1]) && this.GetLambda(mc.Arguments[1]).Parameters.Count == 1) {
                            return this.VisitAggregate(mc.Arguments[0], this.GetLambda(mc.Arguments[1]), SqlNodeType.Avg, mc.Type);
                        }
                        break;
                    case "GroupBy":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 2 &&
                            this.IsLambda(mc.Arguments[1]) && this.GetLambda(mc.Arguments[1]).Parameters.Count == 1) {
                            return this.VisitGroupBy(mc.Arguments[0], this.GetLambda(mc.Arguments[1]), null, null);
                        }
                        else if (mc.Arguments.Count == 3 &&
                            this.IsLambda(mc.Arguments[1]) && this.GetLambda(mc.Arguments[1]).Parameters.Count == 1 &&
                            this.IsLambda(mc.Arguments[2]) && this.GetLambda(mc.Arguments[2]).Parameters.Count == 1) {
                            return this.VisitGroupBy(mc.Arguments[0], this.GetLambda(mc.Arguments[1]), this.GetLambda(mc.Arguments[2]), null);
                        }
                        else if (mc.Arguments.Count == 3 &&
                            this.IsLambda(mc.Arguments[1]) && this.GetLambda(mc.Arguments[1]).Parameters.Count == 1 &&
                            this.IsLambda(mc.Arguments[2]) && this.GetLambda(mc.Arguments[2]).Parameters.Count == 2) {
                            return this.VisitGroupBy(mc.Arguments[0], this.GetLambda(mc.Arguments[1]), null, this.GetLambda(mc.Arguments[2]));
                        }
                        else if (mc.Arguments.Count == 4 &&
                            this.IsLambda(mc.Arguments[1]) && this.GetLambda(mc.Arguments[1]).Parameters.Count == 1 &&
                            this.IsLambda(mc.Arguments[2]) && this.GetLambda(mc.Arguments[2]).Parameters.Count == 1 &&
                            this.IsLambda(mc.Arguments[3]) && this.GetLambda(mc.Arguments[3]).Parameters.Count == 2) {
                            return this.VisitGroupBy(mc.Arguments[0], this.GetLambda(mc.Arguments[1]), this.GetLambda(mc.Arguments[2]), this.GetLambda(mc.Arguments[3]));
                        }
                        break;
                    case "OrderBy":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 2 &&
                            this.IsLambda(mc.Arguments[1]) && this.GetLambda(mc.Arguments[1]).Parameters.Count == 1) {
                            return this.VisitOrderBy(mc.Arguments[0], this.GetLambda(mc.Arguments[1]), SqlOrderType.Ascending);
                        }
                        break;
                    case "OrderByDescending":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 2 &&
                            this.IsLambda(mc.Arguments[1]) && this.GetLambda(mc.Arguments[1]).Parameters.Count == 1) {
                            return this.VisitOrderBy(mc.Arguments[0], this.GetLambda(mc.Arguments[1]), SqlOrderType.Descending);
                        }
                        break;
                    case "ThenBy":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 2 &&
                            this.IsLambda(mc.Arguments[1]) && this.GetLambda(mc.Arguments[1]).Parameters.Count == 1) {
                            return this.VisitThenBy(mc.Arguments[0], this.GetLambda(mc.Arguments[1]), SqlOrderType.Ascending);
                        }
                        break;
                    case "ThenByDescending":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 2 &&
                            this.IsLambda(mc.Arguments[1]) && this.GetLambda(mc.Arguments[1]).Parameters.Count == 1) {
                            return this.VisitThenBy(mc.Arguments[0], this.GetLambda(mc.Arguments[1]), SqlOrderType.Descending);
                        }
                        break;
                    case "Take":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 2) {
                            return this.VisitTake(mc.Arguments[0], mc.Arguments[1]);
                        }
                        break;
                    case "Skip":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 2) {
                            return this.VisitSkip(mc.Arguments[0], mc.Arguments[1]);
                        }
                        break;
                    case "Contains":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 2) {
                            return this.VisitContains(mc.Arguments[0], mc.Arguments[1]);
                        }
                        break;
                    case "ToList":
                    case "AsEnumerable":
                    case "ToArray":
                        isSupportedSequenceOperator = true;
                        if (mc.Arguments.Count == 1) {
                            return this.Visit(mc.Arguments[0]);
                        }
                        break;
                }
                // If the operator is supported, but the particular overload is not,
                // give an appropriate error message
                if (isSupportedSequenceOperator) {
                    throw Error.QueryOperatorOverloadNotSupported(mc.Method.Name);
                }
                throw Error.QueryOperatorNotSupported(mc.Method.Name);
            }
            else {
                throw Error.InvalidSequenceOperatorCall(declType);
            }
        }