Beispiel #1
0
        protected override Expression BuildExecuteCommand(CommandExpression command)
        {
            // parameterize query
            var expression = this.Parameterize(command);

            string commandText = this.Linguist.Format(expression);
            ReadOnlyCollection<NamedValueExpression> namedValues = NamedValueGatherer.Gather(expression);
            QueryCommand qc = new QueryCommand(commandText, namedValues.Select(v => new QueryParameter(v.Name, v.Type, v.QueryType)), false);
            Expression[] values = namedValues.Select(v => Expression.Convert(this.Visit(v.Value), typeof(object))).ToArray();

            if (command is OInsertCommandExpression)
            {
                // insert will directly return a populated instance without the need for a BlockCommandExpression
                // to execute first an INSERT followed by a SELECT - so here we utilize the same Execute method
                // as a projection in order to map the returned values into an entity instance in a single call
                return ExecuteInsert((OInsertCommandExpression)command, qc, values);
            }
            else if (command is OUpdateCommandExpression)
            {
                // update will directly return a populated instance without the need for a BlockCommandExpression
                // to execute first an INSERT followed by a SELECT - so here we utilize the same Execute method
                // as a projection in order to map the returned values into an entity instance in a single call
                return ExecuteUpdate((OUpdateCommandExpression)command, qc, values);
            }
            else
            {
                ProjectionExpression projection = ProjectionFinder.FindProjection(expression);
                if (projection != null)
                {
                    return this.ExecuteProjection(projection, qc, values);
                }
            }

            Expression plan = Expression.Call(this.Executor, "ExecuteCommand", null,
                Expression.Constant(qc),
                Expression.NewArrayInit(typeof(object), values)
                );

            return plan;
        }
Beispiel #2
0
        private Expression ExecuteUpdate(OUpdateCommandExpression update, QueryCommand command, Expression[] values)
        {
            var reader = Expression.Parameter(typeof(FieldReader), "r" + nReaders++);
            var saveScope = this.scope;

            var projection = this.Linguist.Translator.Mapper.GetQueryExpression(new OMappingEntity(update.Projection.Projector.Type, _repoType));
            var fields = new OFieldFinder().Find(update.Projection.Projector).Select(fe => new FieldDeclaration(fe.Name, fe, fe.QueryType)).ToArray();
            var alias = ((FieldExpression)fields[0].Expression).Alias;
            this.scope = new BuilderScope(
                this.scope,
                reader,
                alias,
                fields)
            {
                UseOrdinalMapping = false // we can't guarantee the order that properties will be returned, so we need to read by name
            };
            //var projector = Expression.Lambda(this.Visit(update.Projection.Projector), reader);
            var projector = RedirectProjector(update.Projection.Projector, reader, false);
            this.scope = saveScope;

            var entity = EntityFinder.Find(update.Projection.Projector);

            // call low-level execute directly on supplied DbQueryProvider
            Expression result = Expression.Call(this.Executor, "Execute", new Type[] { update.Identifiable.Entity.EntityType },
                Expression.Constant(command),
                projector,
                Expression.Constant(entity, typeof(MappingEntity)),
                Expression.NewArrayInit(typeof(object), values)
                );

            if (update.Projection.Aggregator != null)
            {
                // apply aggregator
                result = DbExpressionReplacer.Replace(update.Projection.Aggregator.Body, update.Projection.Aggregator.Parameters[0], result);
            }
            return result;
        }
Beispiel #3
0
        protected override Expression ExecuteProjection(ProjectionExpression projection, QueryCommand command, Expression[] values)
        {
            var saveScope = this.Scope;
            ParameterExpression reader = Expression.Parameter(typeof(FieldReader), "r" + nReaders++);
            this.Scope = new BuilderScope(this.Scope, reader, projection.Select.Alias, projection.Select.Fields)
            {
                UseOrdinalMapping = false // orient cannot guarantee ordinally mapped results - must map by name
            };

            var projector = RedirectProjector(projection.Projector, reader, true);

            this.Scope = saveScope;

            var entity = EntityFinder.Find(projection.Projector);

            if (entity != null && entity.EntityType == typeof(_Thing))
            {
                entity = new OMappingEntity(typeof(IIdentifiable),_repoType);
            }

            string methExecute = "Execute";

            // call low-level execute directly on supplied DbQueryProvider
            Expression result = Expression.Call(this.Executor, methExecute, new Type[] { projector.Body.Type },
                Expression.Constant(command),
                projector,
                Expression.Constant(entity, typeof(MappingEntity)),
                Expression.NewArrayInit(typeof(object), values)
                );

            if (projection.Aggregator != null)
            {
                if (projector.ReturnType != projection.Aggregator.Parameters[0].Type.GetGenericArguments()[0])
                {
                    // we probably swaped out an Identifiable type for IIdentifiable, so we need to rebuild the projection
                    // using the interface, otherwise we'll get cast failures downstream
                    projection = new ProjectionExpression(
                        projection.Select,
                        projector,
                        Aggregator.GetAggregator(projector.ReturnType,
                        projection.Aggregator.Parameters[0].Type.GetGenericTypeDefinition().MakeGenericType(projector.ReturnType)));
                }
                // apply aggregator
                result = DbExpressionReplacer.Replace(projection.Aggregator.Body, projection.Aggregator.Parameters[0], result);
            }
            return result;
        }