Пример #1
0
#pragma warning restore 649

        /// <summary>
        /// Process a result operator. If this result is amenable to be made into a function, then
        /// do so.
        /// </summary>
        /// <param name="resultOperator"></param>
        /// <param name="queryModel"></param>
        /// <param name="index"></param>
        public override void VisitResultOperator(ResultOperatorBase resultOperator, QueryModel queryModel, int index)
        {
            // Look for a single-result processor

            var processor = _operators.FindScalarROProcessor(resultOperator.GetType());

            if (processor != null)
            {
                var result = processor.ProcessResultOperator(resultOperator, queryModel, _codeEnv, _codeContext, MEFContainer);
                if (result != null)
                {
                    _codeEnv.SetResult(result);
                    _scoping.Add(_codeContext.Add(queryModel, result));
                }
                return;
            }

            // Look for a sequence processor

            var collectionProcessor = _operators.FindCollectionROProcessor(resultOperator.GetType());

            if (collectionProcessor != null)
            {
                collectionProcessor.ProcessResultOperator(resultOperator, queryModel, _codeEnv, _codeContext, MEFContainer);
                _codeEnv.ResetResult();
                return;
            }

            ///
            /// Uh oh - no idea how to do this!
            ///

            throw new InvalidOperationException("LINQToTTree can't translate the operator '" + resultOperator.ToString() + "'");
        }
Пример #2
0
            /// <summary>
            /// Run a sub-query for the user. The sub-query is a full-blown expression that
            /// must usually run in its own loop (or similar).
            /// </summary>
            /// <remarks>
            /// The query visitor must be re-invoked - this ends up being a full-blown
            /// parsing.
            /// </remarks>
            /// <param name="expression"></param>
            /// <returns></returns>
            protected override Expression VisitSubQuery(SubQueryExpression expression)
            {
                if (MEFContainer == null)
                {
                    throw new InvalidOperationException("MEFContainer can't be null if we need to analyze a sub query!");
                }

                QueryVisitor qv = new QueryVisitor(GeneratedCode, CodeContext, MEFContainer);

                MEFContainer.SatisfyImportsOnce(qv);

                ///
                /// Run it - since this result is out of this loop, we pop-back-out when done.
                ///

                var scope = GeneratedCode.CurrentScope;

                GeneratedCode.SetCurrentScopeAsResultScope();
                qv.VisitQueryModel(expression.QueryModel);

                //
                // And the main index that was looked at we need to cache ourselves.
                //

                if (qv.MainIndexScope != null)
                {
                    CodeContext.CacheVariableToEliminate(qv.MainIndexScope);
                }

                ///
                /// Two possible results from the sub-expression query, and how we proceed depends
                /// on what happened in the sub query
                ///
                /// 1. <returns a value> - an operator like Count() comes back from the sequence.
                ///    it will get used in some later sequence (like # of jets in each event). So,
                ///    we need to make sure it is declared and kept before it is used. The # that comes
                ///    back needs to be used outside the scope we are sitting in - the one that we were at
                ///    when we started this. Since this is a sub-query expression, the result isn't the final
                ///    result, so we need to reset it so no one notices it.
                /// 2. <return a sequence> - this is weird - What we are actually doing here is putting the
                ///    sequence into code. So the loop variable has been updated with the new sequence iterator
                ///    value. But there isn't really a result! So the result will be null...
                ///

                var r = GeneratedCode.ResultValue;

                if (r != null)
                {
                    GeneratedCode.CurrentScope = scope;
                    if (r is IDeclaredParameter)
                    {
                        GeneratedCode.Add(r as IDeclaredParameter, false);
                    }
                    GeneratedCode.ResetResult();
                    return(r);
                }

                //
                // The fact that we returned null means we are dealing with a
                // sequence. There really is no translated version of this expression
                // in that case - so we will return null. If someone above is depending
                // on doing something with it they are going to run into some
                // trouble!

                return(null);
            }