示例#1
0
        public virtual void BuildSelect(Expression selectExpression, TranslationContext context, Type expectedResultType = null)
        {
            // collect columns, split Expression in
            // - things we will do in CLR
            // - things we will do in SQL
            expectedResultType = expectedResultType ?? selectExpression.Type;
            LambdaExpression recordReaderExpr;
            var dataRecordParameter = Expression.Parameter(typeof(IDataRecord), "dataRecord");
            var sessionParameter    = Expression.Parameter(typeof(EntitySession), "session");
            // if we have a GroupByExpression, the result type is not the same:
            // - we need to read what is going to be the Key expression
            // - the final row generator builds a IGrouping<K,T> instead of T
            var selectGroupExpression = selectExpression as GroupExpression;

            if (selectGroupExpression != null)
            {
                var sqlOutExpr    = CutOutSqlTierLambda(selectGroupExpression.GroupedExpression, dataRecordParameter, sessionParameter, null, context);
                var selectKeyExpr = CutOutSqlTierLambda(selectGroupExpression.KeyExpression, dataRecordParameter, sessionParameter, null, context);
                recordReaderExpr = sqlOutExpr;
                if (selectGroupExpression.UseClrGrouping)
                {
                    recordReaderExpr = BuildGroupByPairsReader(sqlOutExpr, selectKeyExpr, dataRecordParameter, sessionParameter, context);
                    var grouper = QueryResultsProcessor.CreateGroupBy(selectKeyExpr.Body.Type, sqlOutExpr.Body.Type);
                    context.CurrentSelect.ResultsProcessor = grouper;
                    context.CurrentSelect.Group.Remove(selectGroupExpression);
                }
            }
            else
            {
                recordReaderExpr = CutOutSqlTierLambda(selectExpression, dataRecordParameter, sessionParameter, expectedResultType, context);
            }
            context.CurrentSelect.Reader = recordReaderExpr;
        }
示例#2
0
        private TranslatedLinqCommand TranslateSelect(LinqCommand command)
        {
            LinqCommandPreprocessor.PreprocessCommand(_dbModel.EntityApp.Model, command);
            var context = new TranslationContext(_dbModel, command);
            var cmdInfo = command.Info;

            // convert lambda params into an initial set of ExternalValueExpression objects;
            foreach (var prm in cmdInfo.Lambda.Parameters)
            {
                var inpParam = new ExternalValueExpression(prm);
                context.ExternalValues.Add(inpParam);
            }
            //Analyze/transform query expression
            var exprChain  = ExpressionChain.Build(cmdInfo.Lambda.Body);
            var selectExpr = BuildSelectExpression(exprChain, context);
            // Analyze external values (parameters?), create DbParameters
            var commandParams = BuildParameters(command, context);
            // If there's at least one parameter that must be converted to literal (ex: value list), we cannot cache the query
            bool canCache = !context.ExternalValues.Any(v => v.SqlUse == ExternalValueSqlUse.Literal);

            if (!canCache)
            {
                command.Info.Flags |= LinqCommandFlags.NoQueryCache;
            }
            //Build SQL, compile object materializer
            var sqlBuilder   = new SqlBuilder(_dbModel);
            var sqlStatement = sqlBuilder.BuildSelect(selectExpr);
            // Parameters are represented as {2}, {3}, etc.
            // Braces in string literals are escaped and are represented as '{0}' and '{1}'
            var sqlTemplate       = sqlStatement.ToString();
            var sql               = FormatSql(sqlTemplate, commandParams);
            var objMaterializer   = CompileObjectMaterializer(context);
            var outType           = context.CurrentSelect.Reader.Body.Type;
            var resultListCreator = ReflectionHelper.GetCompiledGenericListCreator(outType);

            //check if we need to create implicit result set processor
            if (selectExpr.ResultsProcessor == null)
            {
                var returnsResultSet = typeof(IQueryable).IsAssignableFrom(cmdInfo.Lambda.Body.Type);
                if (!returnsResultSet)
                {
                    selectExpr.ResultsProcessor = QueryResultsProcessor.CreateFirstSingleLast("First", outType);
                }
            }
            var sqlQuery = new TranslatedLinqCommand(sqlTemplate, sql, commandParams, command.Info.Flags,
                                                     objMaterializer, selectExpr.ResultsProcessor, resultListCreator);

            return(sqlQuery);
        }