public ProviderQueryExpression(
     IEnumerable<ProviderPropertyExpression> providerProperties,
     ProjectionExpression projection,
     PredicateExpression predicate,
     SortExpressionCollectionExpression sort)
     : this(new ProviderPropertiesExpression(providerProperties), projection, predicate, sort)
 { }
Пример #2
0
 public virtual ProjectionExpression AddOuterJoinTest(ProjectionExpression proj)
 {
     var test = this.GetOuterJoinTest(proj.Select);
     var select = proj.Select;
     ColumnExpression testCol = null;
     // look to see if test expression exists in columns already
     foreach (var col in select.Columns)
     {
         if (test.Equals(col.Expression))
         {
             var colType = SqlType.Get(test.Type);
             testCol = new ColumnExpression(test.Type, colType, select.Alias, col.Name);
             break;
         }
     }
     if (testCol == null)
     {
         // add expression to projection
         testCol = test as ColumnExpression;
         string colName = (testCol != null) ? testCol.Name : "Test";
         colName = proj.Select.Columns.GetAvailableColumnName(colName);
         var colType = SqlType.Get(test.Type);
         select = select.AddColumn(new ColumnDeclaration(colName, test, colType));
         testCol = new ColumnExpression(test.Type, colType, select.Alias, colName);
     }
     var newProjector = new OuterJoinedExpression(testCol, proj.Projector);
     return new ProjectionExpression(select, newProjector, proj.Aggregator);
 }
Пример #3
0
 protected override Expression VisitProjection(ProjectionExpression proj)
 {
     if (proj != root)
         return AliasReplacer.Replace(base.VisitProjection(proj), aliasGenerator);
     else
         return (ProjectionExpression)base.VisitProjection(proj);
 }
Пример #4
0
        protected override Expression VisitProjection(ProjectionExpression proj)
        {
            using (Scope())
            {
                var oldOuterMostSelect = outerMostSelect;
                outerMostSelect = proj.Select;

                var oldHasProjectionInProjector = hasProjectionInProjector;
                hasProjectionInProjector = false;

                Expression projector = this.Visit(proj.Projector);
                SelectExpression source = (SelectExpression)this.Visit(proj.Select);

                hasProjectionInProjector = oldHasProjectionInProjector;
                hasProjectionInProjector |= true;

                outerMostSelect = oldOuterMostSelect;
              

                if (source != proj.Select || projector != proj.Projector)
                    return new ProjectionExpression(source, projector, proj.UniqueFunction, proj.Type);

                return proj;
            }

        }
        public ProviderQueryExpression(
           IEnumerable<ProviderPropertyExpression> providerProperties,
           ProjectionExpression projection,
           PredicateExpression predicate)
            : this(providerProperties, projection, predicate, null)
        {

        }
Пример #6
0
 protected ClientJoinExpression UpdateClientJoin(ClientJoinExpression join, ProjectionExpression projection, IEnumerable<Expression> outerKey, IEnumerable<Expression> innerKey)
 {
     if (projection != join.Projection || outerKey != join.OuterKey || innerKey != join.InnerKey)
     {
         return new ClientJoinExpression(projection, outerKey, innerKey);
     }
     return join;
 }
        public ProviderQueryExpression(
           ProviderPropertiesExpression providerPropertiesExpression,
           ProjectionExpression projection,
           PredicateExpression predicate)
            : this(providerPropertiesExpression, projection, predicate, null)
        {

        }
 protected override Expression VisitProjection(ProjectionExpression proj)
 {
     Expression projector = this.Visit(proj.Projector);
     if (projector != proj.Projector)
     {
         return new ProjectionExpression(proj.Source, projector, proj.Aggregator);
     }
     return proj;
 }
Пример #9
0
 protected override Expression VisitProjection(ProjectionExpression proj)
 {
     // don't parameterize the projector or aggregator!
     SelectExpression select = (SelectExpression)this.Visit(proj.Source);
     if (select != proj.Source) {
         return new ProjectionExpression(select, proj.Projector, proj.Aggregator);
     }
     return proj;
 }
 public ProviderQueryExpression(
     ProviderPropertiesExpression providerPropertiesExpression,
     ProjectionExpression projection,
     PredicateExpression predicate,
     SortExpressionCollectionExpression sort)
     : base(projection, predicate, sort)
 {
     _providerPropertiesExpression = providerPropertiesExpression;
 }
        protected override Expression VisitProjection(ProjectionExpression proj)
        {
            SelectExpression save = this.currentSelect;
            this.currentSelect = proj.Source;
            try
            {
                if (!this.isTopLevel)
                {
                    if (this.CanJoinOnClient(this.currentSelect))
                    {
                        // make a query that combines all the constraints from the outer queries into a single select
                        SelectExpression newOuterSelect = (SelectExpression)QueryDuplicator.Duplicate(save);

                        // remap any references to the outer select to the new alias;
                        SelectExpression newInnerSelect = (SelectExpression)ColumnMapper.Map(proj.Source, newOuterSelect.Alias, save.Alias);
                        // add outer-join test
                        ProjectionExpression newInnerProjection = new ProjectionExpression(newInnerSelect, proj.Projector).AddOuterJoinTest();
                        newInnerSelect = newInnerProjection.Source;
                        Expression newProjector = newInnerProjection.Projector;

                        TableAlias newAlias = new TableAlias();
                        var pc = ColumnProjector.ProjectColumns(this.language.CanBeColumn, newProjector, newOuterSelect.Columns, newAlias, newOuterSelect.Alias, newInnerSelect.Alias);
                        JoinExpression join = new JoinExpression(JoinType.OuterApply, newOuterSelect, newInnerSelect, null);
                        SelectExpression joinedSelect = new SelectExpression(newAlias, pc.Columns, join, null, null, null, proj.IsSingleton, null, null);

                        // apply client-join treatment recursively
                        this.currentSelect = joinedSelect;
                        newProjector = this.Visit(pc.Projector); 

                        // compute keys (this only works if join condition was a single column comparison)
                        List<Expression> outerKeys = new List<Expression>();
                        List<Expression> innerKeys = new List<Expression>();
                        if (this.GetEquiJoinKeyExpressions(newInnerSelect.Where, newOuterSelect.Alias, outerKeys, innerKeys))
                        {
                            // outerKey needs to refer to the outer-scope's alias
                            var outerKey = outerKeys.Select(k => ColumnMapper.Map(k, save.Alias, newOuterSelect.Alias));
                            // innerKey needs to refer to the new alias for the select with the new join
                            var innerKey = innerKeys.Select(k => ColumnMapper.Map(k, joinedSelect.Alias, ((ColumnExpression)k).Alias));
                            ProjectionExpression newProjection = new ProjectionExpression(joinedSelect, newProjector, proj.Aggregator);
                            return new ClientJoinExpression(newProjection, outerKey, innerKey);
                        }
                    }
                }
                else
                {
                    this.isTopLevel = false;
                }

                return base.VisitProjection(proj);
            }
            finally 
            {
                this.currentSelect = save;
            }
        }
Пример #12
0
 protected override Expression VisitProjection(ProjectionExpression proj)
 {
     proj = (ProjectionExpression)base.VisitProjection(proj);
     if (proj.Select.From is SelectExpression) {
         List<SelectExpression> redundant = RedundantSubqueryGatherer.Gather(proj.Select);
         if (redundant != null) {
             proj = SubqueryRemover.Remove(proj, redundant);
         }
     }
     return proj;
 }
Пример #13
0
        static internal ProjectionExpression Flatten(ProjectionExpression proj, AliasGenerator aliasGenerator)
        {
            var result = (ProjectionExpression)new ChildProjectionFlattener { aliasGenerator = aliasGenerator }.Visit(proj);
            if (result == proj)
                return result;

            Expression columnCleaned = UnusedColumnRemover.Remove(result);
            Expression subqueryCleaned = RedundantSubqueryRemover.Remove(columnCleaned);

            return (ProjectionExpression)subqueryCleaned; 
        }
Пример #14
0
 protected override Expression VisitProjection(ProjectionExpression projection)
 {
     // visit mapping in reverse order
     Expression projector = this.Visit(projection.Projector);
     SelectExpression source = (SelectExpression)this.Visit(projection.Source);
     if (projector != projection.Projector || source != projection.Source)
     {
         return new ProjectionExpression(source, projector, projection.Aggregator);
     }
     return projection;
 }
Пример #15
0
 private static ProjectionExpression MergeProjectionExpressions(ProjectionExpression projection,
                                                                ProjectionExpression expression)
 {
     if (projection is AttributesProjectionExpression && expression is AttributesProjectionExpression)
     {
         List<PropertyNameExpression> expr = new List<PropertyNameExpression>();
         expr.AddRange((projection as AttributesProjectionExpression).Attributes.Collection);
         expr.AddRange((expression as AttributesProjectionExpression).Attributes.Collection);
         return new AttributesProjectionExpression(expr);
     }
     throw GetMergeException(projection, expression);
 }
Пример #16
0
        protected override Expression VisitProjection(ProjectionExpression proj)
        {
            this.Visit(proj.Projector);

            SelectExpression source = (SelectExpression)this.Visit(proj.Select);
            Expression projector = this.Visit(proj.Projector);

            if (source != proj.Select || projector != proj.Projector)
            {
                return new ProjectionExpression(source, projector, proj.UniqueFunction, proj.Type);
            }
            return proj;
        }
Пример #17
0
        protected override Expression VisitClientJoin(ClientJoinExpression join)
        {
            // convert client join into a up-front lookup table builder & replace client-join in tree with lookup accessor

            // 1) lookup = query.Select(e => new KVP(key: inner, value: e)).ToLookup(kvp => kvp.Key, kvp => kvp.Value)
            Expression innerKey = MakeJoinKey(join.InnerKey);
            Expression outerKey = MakeJoinKey(join.OuterKey);

            ConstructorInfo kvpConstructor = typeof(KeyValuePair<,>).MakeGenericType(innerKey.Type, join.Projection.Projector.Type).GetConstructor(new System.Type[] { innerKey.Type, join.Projection.Projector.Type });
            Expression constructKVPair = Expression.New(kvpConstructor, innerKey, join.Projection.Projector);
            ProjectionExpression newProjection = new ProjectionExpression(join.Projection.Source, constructKVPair);

            int iLookup = ++nLookup;
            Expression execution = ExecuteProjection(newProjection, false);

            ParameterExpression kvp = Expression.Parameter(constructKVPair.Type, "kvp");

            // filter out nulls
            if (join.Projection.Projector.NodeType == (ExpressionType)DbExpressionType.OuterJoined)
            {
                LambdaExpression pred = Expression.Lambda(
                    Expression.NotEqual(
                        Expression.PropertyOrField(kvp, "Value"),
                        Expression.Constant(null, join.Projection.Projector.Type)
                        ),
                    kvp
                    );
                execution = Expression.Call(typeof(Enumerable), "Where", new System.Type[] { kvp.Type }, execution, pred);
            }

            // make lookup
            LambdaExpression keySelector = Expression.Lambda(Expression.PropertyOrField(kvp, "Key"), kvp);
            LambdaExpression elementSelector = Expression.Lambda(Expression.PropertyOrField(kvp, "Value"), kvp);
            Expression toLookup = Expression.Call(typeof(Enumerable), "ToLookup", new System.Type[] { kvp.Type, outerKey.Type, join.Projection.Projector.Type }, execution, keySelector, elementSelector);

            // 2) agg(lookup[outer])
            ParameterExpression lookup = Expression.Parameter(toLookup.Type, "lookup" + iLookup);
            PropertyInfo property = lookup.Type.GetProperty("Item");
            Expression access = Expression.Call(lookup, property.GetGetMethod(), Visit(outerKey));
            if (join.Projection.Aggregator != null)
            {
                // apply aggregator
                access = DbExpressionReplacer.Replace(join.Projection.Aggregator.Body, join.Projection.Aggregator.Parameters[0], access);
            }

            variables.Add(lookup);
            initializers.Add(toLookup);

            return access;
        }
Пример #18
0
 protected virtual Expression VisitProjection(ProjectionExpression projection)
 {
     this.AddAlias(projection.Source.Alias);
     this.Write("Project(");
     this.WriteLine(Indentation.Inner);
     this.Write("@\"");
     this.Visit(projection.Source);
     this.Write("\",");
     this.WriteLine(Indentation.Same);
     this.Visit(projection.Projector);
     this.Write(",");
     this.WriteLine(Indentation.Same);
     this.Visit(projection.Aggregator);
     this.WriteLine(Indentation.Outer);
     this.Write(")");
     return projection;
 }
        protected override Expression VisitProjection(ProjectionExpression proj)
        {
            if (isTopLevel)
            {
                isTopLevel = false;
                currentSelect = proj.Source;
                Expression projector = Visit(proj.Projector);
                if (projector != proj.Projector || currentSelect != proj.Source)
                {
                    return new ProjectionExpression(currentSelect, projector, proj.Aggregator);
                }
                return proj;
            }

            if (proj.IsSingleton && CanJoinOnServer(currentSelect))
            {
                TableAlias newAlias = new TableAlias();
                currentSelect = currentSelect.AddRedundantSelect(newAlias);

                // remap any references to the outer select to the new alias;
                SelectExpression source =
                    (SelectExpression) ColumnMapper.Map(proj.Source, newAlias, currentSelect.Alias);

                // add outer-join test
                ProjectionExpression pex = new ProjectionExpression(source, proj.Projector).AddOuterJoinTest();

                var pc = ColumnProjector.ProjectColumns(language.CanBeColumn, pex.Projector, currentSelect.Columns,
                                                        currentSelect.Alias, newAlias, proj.Source.Alias);

                JoinExpression join = new JoinExpression(JoinType.OuterApply, currentSelect.From, pex.Source, null);

                currentSelect = new SelectExpression(currentSelect.Alias, pc.Columns, join, null);
                return Visit(pc.Projector);
            }

            var saveTop = isTopLevel;
            var saveSelect = currentSelect;
            isTopLevel = true;
            currentSelect = null;
            Expression result = base.VisitProjection(proj);
            isTopLevel = saveTop;
            currentSelect = saveSelect;
            return result;
        }
Пример #20
0
        public override Expression Translate(Expression expression)
        {
            // fix up any order-by's
            expression = OrderByRewriter.Rewrite(expression);

            expression = base.Translate(expression);

            // convert skip/take info into RowNumber pattern
            if (isPaged(expression))
            {
                //we have some clean up here
                //paging embeds a SELECT in the FROM expression
                //this needs to be reset to the table name
                //and Skip/Take need to be reset
                var projection = expression as ProjectionExpression;

                //pull the select
                SelectExpression outer = projection.Source;

                //take out the nested FROM
                var inner = outer.From as SelectExpression;

                //and stick it on the outer
                outer.From = inner.From;

                //the outer Skip is in place
                //reset the Take since we need both on the Select
                //for the formatter to work
                outer.Take = inner.Take;


                expression = new ProjectionExpression(outer, projection.Projector);
            }

            // fix up any order-by's we may have changed
            expression = OrderByRewriter.Rewrite(expression);

            return expression;
        }
Пример #21
0
 protected abstract Expression VisitProjection(ProjectionExpression projectionExpression);
Пример #22
0
 protected override Expression VisitProjection(ProjectionExpression proj)
 {
     this.Visit(proj.Projector);
     return(proj);
 }
 protected override Expression VisitProjection(ProjectionExpression x)
 {
     return(x?.Update(x.Expression.VisitNode(this)));
 }
Пример #24
0
 protected override Expression VisitProjection(ProjectionExpression projection)
 {
     return(projection);
 }
Пример #25
0
        protected virtual Expression BindGroupBy(Expression source, LambdaExpression keySelector, LambdaExpression elementSelector, LambdaExpression resultSelector)
        {
            var projection = VisitSequence(source);

            _map[keySelector.Parameters[0]] = projection.Projector;
            var keyExpression = Visit(keySelector.Body);

            var elementExpression = projection.Projector;

            if (elementSelector != null)
            {
                _map[elementSelector.Parameters[0]] = projection.Projector;
                elementExpression = Visit(elementSelector.Body);
            }

            var subqueryBasis = VisitSequence(source);

            _map[keySelector.Parameters[0]] = subqueryBasis.Projector;
            var subqueryKeyExpression = Visit(keySelector.Body);

            var subqueryCorrelation = Expression.Equal(keyExpression, subqueryKeyExpression);

            var subqueryElementExpression = subqueryBasis.Projector;

            if (elementSelector != null)
            {
                _map[elementSelector.Parameters[0]] = subqueryBasis.Projector;
                subqueryElementExpression           = Visit(elementSelector.Body);
            }

            var elementAlias      = new Alias();
            var elementProjection = _projector.ProjectFields(subqueryElementExpression, elementAlias, subqueryBasis.Source.Alias);
            var elementSubquery   =
                new ProjectionExpression(
                    new SelectExpression(elementAlias, elementProjection.Fields, subqueryBasis.Source, subqueryCorrelation),
                    elementProjection.Projector);

            var alias = new Alias();

            var info = new GroupByInfo(alias, elementExpression);

            _groupByMap[elementSubquery] = info;

            Expression resultExpression;

            if (resultSelector != null)
            {
                var saveGroupElement = _currentGroupElement;
                _currentGroupElement = elementSubquery;

                _map[resultSelector.Parameters[0]] = keyExpression;
                _map[resultSelector.Parameters[1]] = elementSubquery;
                resultExpression     = Visit(resultSelector.Body);
                _currentGroupElement = saveGroupElement;
            }
            else
            {
                resultExpression = Expression.New(
                    typeof(Grouping <,>).MakeGenericType(keyExpression.Type, subqueryElementExpression.Type).GetConstructors()[0],
                    new[] { keyExpression, elementSubquery });
            }

            var fieldProjection = _projector.ProjectFields(resultExpression, alias, projection.Source.Alias);

            var projectedElementSubquery = ((NewExpression)fieldProjection.Projector).Arguments[1];

            _groupByMap[projectedElementSubquery] = info;

            return(new ProjectionExpression(
                       new SelectExpression(alias, new FieldDeclaration[0], projection.Source, null, null, keyExpression, false, null, null),
                       fieldProjection.Projector));
        }
Пример #26
0
        private Expression BindAggregate(Expression source, MethodInfo method, LambdaExpression argument, bool isRoot)
        {
            Type          returnType           = method.ReturnType;
            AggregateType aggType              = GetAggregateType(method.Name);
            bool          hasPredicateArg      = HasPredicateArg(aggType);
            bool          isDistinct           = false;
            bool          argumentWasPredicate = false;
            bool          useAlternateArg      = false;

            // check for distinct
            MethodCallExpression mcs = source as MethodCallExpression;

            if (mcs != null && !hasPredicateArg && argument == null)
            {
                if (mcs.Method.Name == "Distinct" && mcs.Arguments.Count == 1 &&
                    (mcs.Method.DeclaringType == typeof(Queryable) || mcs.Method.DeclaringType == typeof(Enumerable)))
                {
                    source     = mcs.Arguments[0];
                    isDistinct = true;
                }
            }

            if (argument != null && hasPredicateArg)
            {
                // convert query.Count(predicate) into query.Where(predicate).Count()
                source               = Expression.Call(typeof(Queryable), "Where", method.GetGenericArguments(), source, argument);
                argument             = null;
                argumentWasPredicate = true;
            }

            ProjectionExpression projection = VisitSequence(source);

            Expression argExpr = null;

            if (argument != null)
            {
                map[argument.Parameters[0]] = projection.Projector;
                argExpr = Visit(argument.Body);
            }
            else if (!hasPredicateArg || useAlternateArg)
            {
                argExpr = projection.Projector;
            }

            var              alias   = GetNextAlias();
            var              pc      = ProjectColumns(projection.Projector, alias, projection.Source.Alias);
            Expression       aggExpr = new AggregateExpression(returnType, aggType, argExpr, isDistinct);
            SelectExpression select  = new SelectExpression(alias, new[] { new ColumnDeclaration("", aggExpr) },
                                                            projection.Source, null);

            if (isRoot)
            {
                ParameterExpression p     = Expression.Parameter(typeof(IEnumerable <>).MakeGenericType(aggExpr.Type), "p");
                LambdaExpression    gator =
                    Expression.Lambda(Expression.Call(typeof(Enumerable), "Single", new[] { returnType }, p), p);
                return(new ProjectionExpression(select, new ColumnExpression(returnType, alias, ""), gator));
            }

            ScalarExpression subquery = new ScalarExpression(returnType, select);

            // if we can find the corresponding group-info we can build a special AggregateSubquery node that will enable us to
            // optimize the aggregate expression later using AggregateRewriter
            GroupByInfo info;

            if (!argumentWasPredicate && groupByMap.TryGetValue(projection, out info))
            {
                // use the element expression from the group-by info to rebind the argument so the resulting expression is one that
                // would be legal to add to the columns in the select expression that has the corresponding group-by clause.
                if (argument != null)
                {
                    map[argument.Parameters[0]] = info.Element;
                    argExpr = Visit(argument.Body);
                }
                else if (!hasPredicateArg || useAlternateArg)
                {
                    argExpr = info.Element;
                }
                aggExpr = new AggregateExpression(returnType, aggType, argExpr, isDistinct);

                // check for easy to optimize case.  If the projection that our aggregate is based on is really the 'group' argument from
                // the query.GroupBy(xxx, (key, group) => yyy) method then whatever expression we return here will automatically
                // become part of the select expression that has the group-by clause, so just return the simple aggregate expression.
                if (projection == currentGroupElement)
                {
                    return(aggExpr);
                }

                return(new AggregateSubqueryExpression(info.Alias, aggExpr, subquery));
            }

            return(subquery);
        }
 public Expression VisitProjection(ProjectionExpression proj)
 {
     return(_defaultVisitor.Visit(proj));
 }
Пример #28
0
        protected virtual bool CompareProjection(ProjectionExpression a, ProjectionExpression b)
        {
            if (!this.Compare(a.Select, b.Select))
                return false;

            var save = this.aliasScope;
            try
            {
                this.aliasScope = new ScopedDictionary<TableAlias, TableAlias>(this.aliasScope);
                this.aliasScope.Add(a.Select.Alias, b.Select.Alias);

                return this.Compare(a.Projector, b.Projector)
                    && this.Compare(a.Aggregator, b.Aggregator)
                    && a.IsSingleton == b.IsSingleton;
            }
            finally
            {
                this.aliasScope = save;
            }
        }
Пример #29
0
        public override Expression GetMemberExpression(Expression root, MappingEntity entity, MemberInfo member)
        {
            if (this.mapping.IsAssociationRelationship(entity, member))
            {
                MappingEntity relatedEntity = this.mapping.GetRelatedEntity(entity, member);
                ProjectionExpression projection = this.GetQueryExpression(relatedEntity);

                // make where clause for joining back to 'root'
                var declaredTypeMembers = this.mapping.GetAssociationKeyMembers(entity, member).ToList();
                var associatedMembers = this.mapping.GetAssociationRelatedKeyMembers(entity, member).ToList();

                Expression where = null;
                for (int i = 0, n = associatedMembers.Count; i < n; i++)
                {
                    Expression equal = 
                        this.GetMemberExpression(projection.Projector, relatedEntity, associatedMembers[i]).Equal(
                            this.GetMemberExpression(root, entity, declaredTypeMembers[i])
                        );
                    where = (where != null) ? where.And(equal) : equal;
                }

                TableAlias newAlias = new TableAlias();
                var pc = ColumnProjector.ProjectColumns(this.translator.Linguist.Language, projection.Projector, null, newAlias, projection.Select.Alias);

                LambdaExpression aggregator = Aggregator.GetAggregator(TypeHelper.GetMemberType(member), typeof(IEnumerable<>).MakeGenericType(pc.Projector.Type));
                var result = new ProjectionExpression(
                    new SelectExpression(newAlias, pc.Columns, projection.Select, where),
                    pc.Projector, aggregator
                    );

                return this.translator.Police.ApplyPolicy(result, member);
            }
            else
            {
                AliasedExpression aliasedRoot = root as AliasedExpression;
                if (aliasedRoot != null && this.mapping.IsColumn(entity, member))
                {
                    return new ColumnExpression(TypeHelper.GetMemberType(member), this.GetColumnType(entity, member), aliasedRoot.Alias, this.mapping.GetColumnName(entity, member));
                }
                return QueryBinder.BindMember(root, member);
            }
        }
Пример #30
0
 protected override Expression VisitProjection(ProjectionExpression projection)
 {
     // visit mapping in reverse order
     Expression projector = this.Visit(projection.Projector);
     SelectExpression select = (SelectExpression)this.Visit(projection.Select);
     return this.UpdateProjection(projection, select, projector, projection.Aggregator);
 }
 public FeatureQueryExpression(ProjectionExpression projection,
                               PredicateExpression predicate, SortExpressionCollectionExpression sort)
     : base(projection, predicate, sort)
 {
 }
 public ISourceInjectedQueryable <TDestination> For <TDestination>(params Expression <Func <TDestination, object> >[] membersToExpand)
 {
     _membersToExpand = ProjectionExpression.GetMemberPaths(membersToExpand);
     return(CreateQueryable <TDestination>());
 }
Пример #33
0
        private TranslatedQuery PrepareSubqueryParameters(SubQueryExpression subQueryExpression, out Parameter <Tuple> parameterOfTuple, out Type elementType, out ProjectionExpression projection)
        {
            // 1. Rewrite recordset and ItemProjector to parameter<tuple>
            var subqueryTupleParameter = context.GetTupleParameter(subQueryExpression.OuterParameter);
            var newDataSource          = ApplyParameterToTupleParameterRewriter.Rewrite(
                subQueryExpression.ProjectionExpression.ItemProjector.DataSource,
                subqueryTupleParameter,
                subQueryExpression.ApplyParameter);

            var newItemProjectorBody = ApplyParameterToTupleParameterRewriter.Rewrite(
                subQueryExpression.ProjectionExpression.ItemProjector.Item,
                subqueryTupleParameter,
                subQueryExpression.ApplyParameter);

            var itemProjector = new ItemProjectorExpression(newItemProjectorBody, newDataSource, subQueryExpression.ProjectionExpression.ItemProjector.Context);

            parameterOfTuple = context.GetTupleParameter(subQueryExpression.OuterParameter);

            // 2. Add only parameter<tuple>. Tuple value will be assigned
            // at the moment of materialization in SubQuery constructor
            projection = new ProjectionExpression(
                subQueryExpression.ProjectionExpression.Type,
                itemProjector,
                subQueryExpression.ProjectionExpression.TupleParameterBindings,
                subQueryExpression.ProjectionExpression.ResultAccessMethod);

            // 3. Make translation
            elementType = subQueryExpression.ProjectionExpression.ItemProjector.Item.Type;
            var translateMethod = Translator.TranslateMethod;

            return((TranslatedQuery)translateMethod.Invoke(
                       context.Translator,
                       new object[] { projection, tupleParameters.Append(parameterOfTuple) }));
        }
Пример #34
0
 protected internal override Expression VisitProjection(ProjectionExpression proj)
 {
     throw new InvalidOperationException("No ProjectionExpressions expected at this stage");
 }
Пример #35
0
        protected override Expression VisitProjection(ProjectionExpression proj)
        {
            var projector = Visit(proj.Projector);

            return(proj.Update(proj.Select, projector, proj.Aggregator));
        }
Пример #36
0
    internal static ITranslateResult Build(ProjectionExpression proj)
    {
        Type type = proj.UniqueFunction == null?proj.Type.ElementType() !: proj.Type;

        return(miBuildPrivate.GetInvoker(type)(proj));
    }
Пример #37
0
        internal static Expression BindMember(Expression source, MemberInfo member)
        {
            switch (source.NodeType)
            {
            case ExpressionType.MemberInit:
                MemberInitExpression min = (MemberInitExpression)source;
                for (int i = 0, n = min.Bindings.Count; i < n; i++)
                {
                    MemberAssignment assign = min.Bindings[i] as MemberAssignment;
                    if (assign != null && MembersMatch(assign.Member, member))
                    {
                        return(assign.Expression);
                    }
                }
                break;

            case ExpressionType.New:
                NewExpression nex = (NewExpression)source;
                if (nex.Members != null)
                {
                    for (int i = 0, n = nex.Members.Count; i < n; i++)
                    {
                        if (MembersMatch(nex.Members[i], member))
                        {
                            return(nex.Arguments[i]);
                        }
                    }
                }
                else if (nex.Type.IsGenericType && nex.Type.GetGenericTypeDefinition() == typeof(Grouping <,>))
                {
                    if (member.Name == "Key")
                    {
                        return(nex.Arguments[0]);
                    }
                }
                break;

            case (ExpressionType)DbExpressionType.Projection:
                // member access on a projection turns into a new projection w/ member access applied
                ProjectionExpression proj         = (ProjectionExpression)source;
                Expression           newProjector = BindMember(proj.Projector, member);
                return(new ProjectionExpression(proj.Source, newProjector));

            case (ExpressionType)DbExpressionType.OuterJoined:
                OuterJoinedExpression oj = (OuterJoinedExpression)source;
                Expression            em = BindMember(oj.Expression, member);
                if (em is ColumnExpression)
                {
                    return(em);
                }
                return(new OuterJoinedExpression(oj.Test, em));

            case ExpressionType.Conditional:
                ConditionalExpression cex = (ConditionalExpression)source;
                return(Expression.Condition(cex.Test, BindMember(cex.IfTrue, member),
                                            BindMember(cex.IfFalse, member)));

            case ExpressionType.Constant:
                ConstantExpression con = (ConstantExpression)source;
                if (con.Value == null)
                {
                    Type memberType = TypeHelper.GetMemberType(member);
                    return(Expression.Constant(GetDefault(memberType), memberType));
                }
                break;
            }
            return(Expression.MakeMemberAccess(source, member));
        }
Пример #38
0
 protected override Expression VisitProjection(ProjectionExpression proj)
 {
     // treat these like scalar subqueries
     if ((proj.Projector is ColumnExpression) || this.forDebug)
     {
         this.Write("(");
         this.WriteLine(Indentation.Inner);
         this.Visit(proj.Select);
         this.Write(")");
         this.Indent(Indentation.Outer);
     }
     else
     {
         throw new NotSupportedException("Non-scalar projections cannot be translated to SQL.");
     }
     return proj;
 }
Пример #39
0
        protected virtual Expression BindGroupBy(Expression source, LambdaExpression keySelector,
                                                 LambdaExpression elementSelector, LambdaExpression resultSelector)
        {
            ProjectionExpression projection = VisitSequence(source);

            map[keySelector.Parameters[0]] = projection.Projector;
            Expression keyExpr = Visit(keySelector.Body);

            Expression elemExpr = projection.Projector;

            if (elementSelector != null)
            {
                map[elementSelector.Parameters[0]] = projection.Projector;
                elemExpr = Visit(elementSelector.Body);
            }

            // Use ProjectColumns to get group-by expressions from key expression
            ProjectedColumns         keyProjection = ProjectColumns(keyExpr, projection.Source.Alias, projection.Source.Alias);
            IEnumerable <Expression> groupExprs    = keyProjection.Columns.Select(c => c.Expression);

            // make duplicate of source query as basis of element subquery by visiting the source again
            ProjectionExpression subqueryBasis = VisitSequence(source);

            // recompute key columns for group expressions relative to subquery (need these for doing the correlation predicate)
            map[keySelector.Parameters[0]] = subqueryBasis.Projector;
            Expression subqueryKey = Visit(keySelector.Body);

            // use same projection trick to get group-by expressions based on subquery
            ProjectedColumns subqueryKeyPC = ProjectColumns(subqueryKey, subqueryBasis.Source.Alias,
                                                            subqueryBasis.Source.Alias);
            IEnumerable <Expression> subqueryGroupExprs = subqueryKeyPC.Columns.Select(c => c.Expression);
            Expression subqueryCorrelation = BuildPredicateWithNullsEqual(subqueryGroupExprs, groupExprs);

            // compute element based on duplicated subquery
            Expression subqueryElemExpr = subqueryBasis.Projector;

            if (elementSelector != null)
            {
                map[elementSelector.Parameters[0]] = subqueryBasis.Projector;
                subqueryElemExpr = Visit(elementSelector.Body);
            }

            // build subquery that projects the desired element
            var elementAlias = GetNextAlias();
            ProjectedColumns     elementPC       = ProjectColumns(subqueryElemExpr, elementAlias, subqueryBasis.Source.Alias);
            ProjectionExpression elementSubquery =
                new ProjectionExpression(
                    new SelectExpression(elementAlias, elementPC.Columns, subqueryBasis.Source, subqueryCorrelation),
                    elementPC.Projector
                    );

            var alias = GetNextAlias();

            // make it possible to tie aggregates back to this group-by
            GroupByInfo info = new GroupByInfo(alias, elemExpr);

            groupByMap.Add(elementSubquery, info);

            Expression resultExpr;

            if (resultSelector != null)
            {
                Expression saveGroupElement = currentGroupElement;
                currentGroupElement = elementSubquery;
                // compute result expression based on key and element-subquery
                map[resultSelector.Parameters[0]] = keyProjection.Projector;
                map[resultSelector.Parameters[1]] = elementSubquery;
                resultExpr          = Visit(resultSelector.Body);
                currentGroupElement = saveGroupElement;
            }
            else
            {
                // result must be IGrouping<K,E>
                resultExpr =
                    Expression.New(
                        typeof(Grouping <,>).MakeGenericType(keyExpr.Type, subqueryElemExpr.Type).GetConstructors()[0],
                        new[] { keyExpr, elementSubquery }
                        );
            }

            ProjectedColumns pc = ProjectColumns(resultExpr, alias, projection.Source.Alias);

            // make it possible to tie aggregates back to this group-by
            Expression projectedElementSubquery = ((NewExpression)pc.Projector).Arguments[1];

            groupByMap.Add(projectedElementSubquery, info);

            return(new ProjectionExpression(
                       new SelectExpression(alias, pc.Columns, projection.Source, null, null, groupExprs),
                       pc.Projector
                       ));
        }
Пример #40
0
 public Grouping(ProjectionExpression projectionExpression, TranslatedQuery translatedQuery, Parameter <Tuple> parameter, Tuple tuple, TKey key, ItemMaterializationContext context)
     : base(projectionExpression, translatedQuery, parameter, tuple, context)
 {
     Key = key;
 }
Пример #41
0
 protected virtual Expression VisitProjectionExpression(ProjectionExpression projectionExpression)
 {
     return(projectionExpression);
 }
Пример #42
0
            protected override Expression VisitProjection(ProjectionExpression proj)
            {
                SelectExpression select = (SelectExpression)this.Visit(proj.Select);

                return(this.UpdateProjection(proj, select, proj.Projector, proj.Aggregator));
            }
Пример #43
0
        public virtual Expression GetInsertResult(IEntityMapping mapping, Expression instance, LambdaExpression selector, Dictionary <MemberInfo, Expression> map)
        {
            var tableAlias = new TableAlias();
            var tex        = new TableExpression(tableAlias, mapping);
            var aggregator = Aggregator.GetAggregator(selector.Body.Type, typeof(IEnumerable <>).MakeGenericType(selector.Body.Type));

            Expression where = null;
            DeclarationCommand genIdCommand = null;
            var generatedIds = mapping.PrimaryKeys.Where(m => m.IsPrimaryKey && m.IsGenerated).ToList();

            if (generatedIds.Count > 0)
            {
                if (map == null || !generatedIds.Any(m => map.ContainsKey(m.Member)))
                {
                    var localMap = new Dictionary <MemberInfo, Expression>();
                    genIdCommand = this.GetGeneratedIdCommand(mapping, generatedIds, localMap);
                    map          = localMap;
                }

                // is this just a retrieval of one generated id member?
                var mex = selector.Body as MemberExpression;
                if (mex != null)
                {
                    var id = mapping.Get(mex.Member);
                    if (id != null && id.IsPrimaryKey && id.IsGenerated)
                    {
                        if (genIdCommand != null)
                        {
                            // just use the select from the genIdCommand
                            return(new ProjectionExpression(
                                       genIdCommand.Source,
                                       new ColumnExpression(mex.Type, genIdCommand.Variables[0].SqlType, genIdCommand.Source.Alias, genIdCommand.Source.Columns[0].Name),
                                       aggregator
                                       ));
                        }
                        else
                        {
                            TableAlias alias   = new TableAlias();
                            var        colType = id.SqlType;
                            return(new ProjectionExpression(
                                       new SelectExpression(alias, new[] { new ColumnDeclaration("", map[mex.Member], colType) }, null, null),
                                       new ColumnExpression(mex.Member.GetMemberType(), colType, alias, ""),
                                       aggregator
                                       ));
                        }
                    }

                    where = generatedIds.Select((m, i) =>
                                                this.GetMemberExpression(tex, mapping, m.Member).Equal(map[m.Member])
                                                ).Aggregate((x, y) => x.And(y));
                }
            }
            else
            {
                where = this.GetIdentityCheck(tex, mapping, instance);
            }

            Expression typeProjector = this.GetEntityExpression(tex, mapping);
            Expression selection     = DbExpressionReplacer.Replace(selector.Body, selector.Parameters[0], typeProjector);
            TableAlias newAlias      = new TableAlias();
            var        pc            = ColumnProjector.ProjectColumns(selection, null, newAlias, tableAlias);
            var        pe            = new ProjectionExpression(
                new SelectExpression(newAlias, pc.Columns, tex, where),
                pc.Projector,
                aggregator
                );

            if (genIdCommand != null)
            {
                return(new BlockCommand(genIdCommand, pe));
            }
            return(pe);
        }
Пример #44
0
 protected override Expression VisitProjection(ProjectionExpression proj)
 {
     this.found = proj;
     return(proj);
 }
 public ISourceInjectedQueryable <TDestination> For <TDestination>(IObjectDictionary parameters, params string[] membersToExpand)
 {
     _parameters      = parameters;
     _membersToExpand = ProjectionExpression.GetMemberPaths(typeof(TDestination), membersToExpand);
     return(CreateQueryable <TDestination>());
 }
Пример #46
0
 protected override Expression VisitProjection(ProjectionExpression projection)
 {
     Visit(projection.Source);
     return(projection);
 }
Пример #47
0
 private Expression BindFirst(Expression source, LambdaExpression predicate, string kind, bool isRoot)
 {
     ProjectionExpression projection = this.VisitSequence(source);
     Expression where = null;
     if (predicate != null)
     {
         this.map[predicate.Parameters[0]] = projection.Projector;
         where = this.Visit(predicate.Body);
     }
     bool isFirst = kind.StartsWith("First");
     bool isLast = kind.StartsWith("Last");
     Expression take = (isFirst || isLast) ? Expression.Constant(1) : null;
     if (take != null || where != null)
     {
         var alias = this.GetNextAlias();
         ProjectedColumns pc = this.ProjectColumns(projection.Projector, alias, projection.Select.Alias);
         projection = new ProjectionExpression(
             new SelectExpression(alias, pc.Columns, projection.Select, where, null, null, false, null, take, isLast),
             pc.Projector
             );
     }
     if (isRoot)
     {
         Type elementType = projection.Projector.Type;
         ParameterExpression p = Expression.Parameter(typeof(IEnumerable<>).MakeGenericType(elementType), "p");
         LambdaExpression gator = Expression.Lambda(Expression.Call(typeof(Enumerable), kind, new Type[] { elementType }, p), p);
         return new ProjectionExpression(projection.Select, projection.Projector, gator);
     }
     return projection;
 }
 protected abstract Expression VisitProjection([NotNull] ProjectionExpression projectionExpression);
Пример #49
0
        public override ProjectionExpression GetQueryExpression(MappingEntity entity)
        {
            var tableAlias = new TableAlias();
            var selectAlias = new TableAlias();
            var table = new TableExpression(tableAlias, entity, this.mapping.GetTableName(entity));

            Expression projector = this.GetEntityExpression(table, entity);
            var pc = ColumnProjector.ProjectColumns(this.translator.Linguist.Language, projector, null, selectAlias, tableAlias);

            var proj = new ProjectionExpression(
                new SelectExpression(selectAlias, pc.Columns, table, null),
                pc.Projector
                );

            return (ProjectionExpression)this.Translator.Police.ApplyPolicy(proj, entity.ElementType);
        }
 private static bool IsNullableProjection(ProjectionExpression projection)
 {
     return(projection.Expression is ColumnExpression column ? column.Nullable : true);
 }
Пример #51
0
        protected virtual Expression GetInsertResult(MappingEntity entity, Expression instance, LambdaExpression selector, Dictionary<MemberInfo, Expression> map)
        {
            var tableAlias = new TableAlias();
            var tex = new TableExpression(tableAlias, entity, this.mapping.GetTableName(entity));
            var aggregator = Aggregator.GetAggregator(selector.Body.Type, typeof(IEnumerable<>).MakeGenericType(selector.Body.Type));

            Expression where;
            DeclarationCommand genIdCommand = null;
            var generatedIds = this.mapping.GetMappedMembers(entity).Where(m => this.mapping.IsPrimaryKey(entity, m) && this.mapping.IsGenerated(entity, m)).ToList();
            if (generatedIds.Count > 0)
            {
                if (map == null || !generatedIds.Any(m => map.ContainsKey(m)))
                {
                    var localMap = new Dictionary<MemberInfo, Expression>();
                    genIdCommand = this.GetGeneratedIdCommand(entity, generatedIds.ToList(), localMap);
                    map = localMap;
                }

                // is this just a retrieval of one generated id member?
                var mex = selector.Body as MemberExpression;
                if (mex != null && this.mapping.IsPrimaryKey(entity, mex.Member) && this.mapping.IsGenerated(entity, mex.Member))
                {
                    if (genIdCommand != null)
                    {
                        // just use the select from the genIdCommand
                        return new ProjectionExpression(
                            genIdCommand.Source,
                            new ColumnExpression(mex.Type, genIdCommand.Variables[0].QueryType, genIdCommand.Source.Alias, genIdCommand.Source.Columns[0].Name),
                            aggregator
                            );
                    }
                    else
                    {
                        TableAlias alias = new TableAlias();
                        var colType = this.GetColumnType(entity, mex.Member);
                        return new ProjectionExpression(
                            new SelectExpression(alias, new[] { new ColumnDeclaration("", map[mex.Member], colType) }, null, null),
                            new ColumnExpression(TypeHelper.GetMemberType(mex.Member), colType, alias, ""),
                            aggregator
                            );
                    }
                }

                where = generatedIds.Select((m, i) =>
                    this.GetMemberExpression(tex, entity, m).Equal(map[m])
                    ).Aggregate((x, y) => x.And(y));
            }
            else
            {
                where = this.GetIdentityCheck(tex, entity, instance);
            }

            Expression typeProjector = this.GetEntityExpression(tex, entity);
            Expression selection = DbExpressionReplacer.Replace(selector.Body, selector.Parameters[0], typeProjector);
            TableAlias newAlias = new TableAlias();
            var pc = ColumnProjector.ProjectColumns(this.translator.Linguist.Language, selection, null, newAlias, tableAlias);
            var pe = new ProjectionExpression(
                new SelectExpression(newAlias, pc.Columns, tex, where),
                pc.Projector,
                aggregator
                );

            if (genIdCommand != null)
            {
                return new BlockCommand(genIdCommand, pe);
            }
            return pe;
        }
        public TResult Execute <TResult>(Expression expression)
        {
            try
            {
                var resultType = typeof(TResult);
                Inspector.StartQueryExecuteInterceptor(resultType, expression);

                var sourceExpression = ConvertDestinationExpressionToSourceExpression(expression);

                var destResultType   = typeof(TResult);
                var sourceResultType = CreateSourceResultType(destResultType);

                object destResult = null;

                // case #1: query is a projection from complex Source to complex Destination
                // example: users.UseAsDataSource().For<UserDto>().Where(x => x.Age > 20).ToList()
                if (IsProjection <TDestination>(resultType))
                {
                    // in case of a projection, we need an IQueryable
                    var sourceResult = _dataSource.Provider.CreateQuery(sourceExpression);
                    Inspector.SourceResult(sourceExpression, sourceResult);

                    destResult = new ProjectionExpression((IQueryable <TSource>)sourceResult, _mapper.ConfigurationProvider.ExpressionBuilder).To <TDestination>(_parameters, _membersToExpand);
                }
                // case #2: query is arbitrary ("manual") projection
                // exaple: users.UseAsDataSource().For<UserDto>().Select(user => user.Age).ToList()
                // in case an arbitrary select-statement is enumerated, we do not need to map the expression at all
                // and cann safely return it
                else if (IsProjection(resultType, sourceExpression))
                {
                    var sourceResult    = _dataSource.Provider.CreateQuery(sourceExpression);
                    var enumerator      = sourceResult.GetEnumerator();
                    var elementType     = ElementTypeHelper.GetElementType(typeof(TResult));
                    var constructorInfo = typeof(List <>).MakeGenericType(elementType).GetDeclaredConstructor(new Type[0]);
                    if (constructorInfo != null)
                    {
                        var listInstance = (IList)constructorInfo.Invoke(null);
                        while (enumerator.MoveNext())
                        {
                            listInstance.Add(enumerator.Current);
                        }
                        destResult = listInstance;
                    }
                }
                // case #2: projection to simple type
                // example: users.UseAsDataSource().For<UserDto>().FirstOrDefault(user => user.Age > 20)
                else
                {
                    /*
                     *  in case of an element result (so instead of IQueryable<TResult>, just TResult)
                     *  we still want to support parameters.
                     *  This is e.g. the case, when the developer writes "UseAsDataSource().For<TResult>().FirstOrDefault(x => ...)
                     *  To still be able to support parameters, we need to create a query from it.
                     *  That said, we need to replace the "element" operator "FirstOrDefault" with a "Where" operator, then apply our "Select"
                     *  to map from TSource to TResult and finally re-apply the "element" operator ("FirstOrDefault" in our case) so only
                     *  one element is returned by our "Execute<TResult>" method. Otherwise we'd get an InvalidCastException
                     *
                     * So first we visit the sourceExpression and replace "element operators" with "where"
                     * then we create our mapping expression from TSource to TDestination (select) and apply it
                     * finally, we search for the element expression overload of our replaced "element operator" that has no expression as parameter
                     *      this expression is not needed anymore as it has already been applied to the "Where" operation and can be safely omitted
                     * when we're done creating our new expression, we call the underlying provider to execute it
                     */

                    // as we need to replace the innermost element of the expression,
                    // we need to traverse it first in order to find the node to replace or potential caveats
                    // e.g. .UseAsDataSource().For<Dto>().Select(e => e.Name).First()
                    //      in the above case we cannot map anymore as the "select" operator overrides our mapping.
                    var searcher = new ReplaceableMethodNodeFinder <TSource>();
                    searcher.Visit(sourceExpression);
                    // provide the replacer with our found MethodNode or <null>
                    var replacer = new MethodNodeReplacer <TSource>(searcher.MethodNode);

                    // default back to simple mapping of object instance for backwards compatibility (e.g. mapping non-nullable to nullable fields)
                    sourceExpression = replacer.Visit(sourceExpression);

                    if (replacer.FoundElementOperator)
                    {
                        /*  in case of primitive element operators (e.g. Any(), Sum()...)
                         *  we need to map the originating types (e.g. Entity to Dto) in this query
                         *  as the final value will be projected automatically
                         *
                         *  == example 1 ==
                         *  UseAsDataSource().For<Dto>().Any(entity => entity.Name == "thename")
                         *  ..in that case sourceResultType and destResultType would both be "Boolean" which is not mappable for AutoMapper
                         *
                         *  == example 2 ==
                         *  UseAsDataSource().For<Dto>().FirstOrDefault(entity => entity.Name == "thename")
                         *  ..in this case the sourceResultType would be Entity and the destResultType Dto, so we can map the query directly
                         */

                        if (sourceResultType == destResultType)// && destResultType.IsPrimitive)
                        {
                            sourceResultType = typeof(TSource);
                            destResultType   = typeof(TDestination);
                        }

                        var membersToExpand = _membersToExpand.SelectMany(m => m).Distinct().ToArray();
                        var lambdas         = _mapper.ConfigurationProvider.ExpressionBuilder.GetMapExpression(sourceResultType, destResultType,
                                                                                                               _parameters, membersToExpand);
                        // add projection via "select" operator
                        var expr = lambdas.Aggregate(sourceExpression, (source, lambda) => Select(source, lambda));
                        // in case an element operator without predicate expression was found (and thus not replaced)
                        var replacementMethod = replacer.ElementOperator;
                        // in case an element operator with predicate expression was replaced
                        if (replacer.ReplacedMethod != null)
                        {
                            // find replacement method that has no more predicates
                            replacementMethod = typeof(Queryable).GetAllMethods()
                                                .Single(m => m.Name == replacer.ReplacedMethod.Name
#if NET45
                                                        && m.GetParameters().All(p => typeof(Queryable).IsAssignableFrom(p.Member.ReflectedType))
#endif
                                                        && m.GetParameters().Length == replacer.ReplacedMethod.GetParameters().Length - 1);
                        }

                        // reintroduce element operator that was replaced with a "where" operator to make it queryable
                        expr = Expression.Call(null,
                                               replacementMethod.MakeGenericMethod(destResultType), expr);

                        destResult = _dataSource.Provider.Execute(expr);
                    }
                    // If there was no element operator that needed to be replaced by "where", just map the result
                    else
                    {
                        var sourceResult = _dataSource.Provider.Execute(sourceExpression);
                        Inspector.SourceResult(sourceExpression, sourceResult);
                        destResult = _mapper.Map(sourceResult, sourceResultType, destResultType);
                    }
                }

                Inspector.DestResult(destResult);

                // implicitly convert types in case of valuetypes which cannot be casted explicitly
                if (typeof(TResult).IsValueType() && destResult?.GetType() != typeof(TResult))
                {
                    return((TResult)Convert.ChangeType(destResult, typeof(TResult)));
                }

                // if it is not a valuetype, we can safely cast it
                return((TResult)destResult);
            }
            catch (Exception x)
            {
                _exceptionHandler(x);
                throw;
            }
        }
Пример #53
0
 protected virtual Expression VisitProjection(ProjectionExpression proj)
 {
     SelectExpression source = (SelectExpression)this.Visit(proj.Source);
     Expression projector = this.Visit(proj.Projector);
     if (source != proj.Source || projector != proj.Projector)
     {
         return new ProjectionExpression(source, projector, proj.Aggregator);
     }
     return proj;
 }
Пример #54
0
 public static ProjectionExpression Remove(ProjectionExpression projection, params SelectExpression[] selectsToRemove)
 {
     return(Remove(projection, (IEnumerable <SelectExpression>)selectsToRemove));
 }
Пример #55
0
        protected override Expression VisitProjection(ProjectionExpression proj)
        {
            if (currentSource == null)
            {
                currentSource = WithoutOrder(proj.Select);

                Expression projector = this.Visit(proj.Projector);

                if (projector != proj.Projector)
                    proj = new ProjectionExpression(proj.Select, projector, proj.UniqueFunction, proj.Type);

                currentSource = null;
                return proj;
            }
            else
            {
                HashSet<ColumnExpression> columns = ExternalColumnGatherer.Gatherer(proj, currentSource.Alias);

                if (columns.Count == 0)
                {
                    Expression projector = Visit(proj.Projector);

                    ConstantExpression key = Expression.Constant(0);
                    Type kvpType = typeof(KeyValuePair<,>).MakeGenericType(key.Type, projector.Type);
                    ConstructorInfo ciKVP = kvpType.GetConstructor(new[] { key.Type, projector.Type });
                    Type projType = proj.UniqueFunction == null ? typeof(IEnumerable<>).MakeGenericType(kvpType) : kvpType;

                    var childProj = new ProjectionExpression(proj.Select, 
                        Expression.New(ciKVP, key, projector), proj.UniqueFunction, projType);

                    return new ChildProjectionExpression(childProj,
                        Expression.Constant(0), inMList, proj.Type, new LookupToken());

                }
                else
                {
                    SelectExpression external;
                    IEnumerable<ColumnExpression> externalColumns;

                    if (!IsKey(currentSource, columns))
                    {
                        Alias aliasDistinct = aliasGenerator.GetUniqueAlias(currentSource.Alias.Name + "D");
                        ColumnGenerator generatorDistinct = new ColumnGenerator();

                        List<ColumnDeclaration> columnDistinct = columns.Select(ce => generatorDistinct.MapColumn(ce)).ToList();
                        external = new SelectExpression(aliasDistinct, true, null, columnDistinct, currentSource, null, null, null, 0);


                        Dictionary<ColumnExpression, ColumnExpression> distinctReplacements = columnDistinct.ToDictionary(
                                                    cd => (ColumnExpression)cd.Expression,
                                                    cd => cd.GetReference(aliasDistinct));

                        proj = (ProjectionExpression)ColumnReplacer.Replace(proj, distinctReplacements);

                        externalColumns = distinctReplacements.Values.ToHashSet();
                    }
                    else
                    {
                        external = currentSource;
                        externalColumns = columns;
                    }

                    ColumnGenerator generatorSM = new ColumnGenerator();
                    List<ColumnDeclaration> columnsSMExternal = externalColumns.Select(ce => generatorSM.MapColumn(ce)).ToList();
                    List<ColumnDeclaration> columnsSMInternal = proj.Select.Columns.Select(cd => generatorSM.MapColumn(cd.GetReference(proj.Select.Alias))).ToList();

                    List<OrderExpression> innerOrders;
                    SelectExpression @internal = ExtractOrders(proj.Select, out innerOrders);

                    Alias aliasSM = aliasGenerator.GetUniqueAlias(@internal.Alias.Name + "SM");
                    SelectExpression selectMany = new SelectExpression(aliasSM, false, null, columnsSMExternal.Concat(columnsSMInternal),
                        new JoinExpression(JoinType.CrossApply,
                            external,
                            @internal, null), null, innerOrders, null, 0);

                    SelectExpression old = currentSource;
                    currentSource = WithoutOrder(selectMany);

                    var selectManyReplacements = selectMany.Columns.ToDictionary(
                           cd => (ColumnExpression)cd.Expression,
                           cd => cd.GetReference(aliasSM));

                    Expression projector = ColumnReplacer.Replace(proj.Projector, selectManyReplacements);

                    projector = Visit(projector);

                    currentSource = old;

                    Expression key = TupleReflection.TupleChainConstructor(columnsSMExternal.Select(cd => cd.GetReference(aliasSM).Nullify()));
                    Type kvpType = typeof(KeyValuePair<,>).MakeGenericType(key.Type, projector.Type);
                    ConstructorInfo ciKVP = kvpType.GetConstructor(new[] { key.Type, projector.Type });
                    Type projType = proj.UniqueFunction == null ? typeof(IEnumerable<>).MakeGenericType(kvpType) : kvpType;

                    var childProj = new ProjectionExpression(selectMany,
                        Expression.New(ciKVP, key, projector), proj.UniqueFunction, projType);

                    return new ChildProjectionExpression(childProj,
                        TupleReflection.TupleChainConstructor(columns.Select(a => a.Nullify())), inMList, proj.Type, new LookupToken());
                }
            }
        }
Пример #56
0
 public static ProjectionExpression Remove(ProjectionExpression projection, IEnumerable <SelectExpression> selectsToRemove)
 {
     return((ProjectionExpression) new SubqueryRemover(selectsToRemove).Visit(projection));
 }
Пример #57
0
        public override ProjectionExpression GetQueryExpression(MappingEntity entity)
        {
            var tables = this.mapping.GetTables(entity);
            if (tables.Count <= 1)
            {
                return base.GetQueryExpression(entity);
            }

            var aliases = new Dictionary<string, TableAlias>();
            MappingTable rootTable = tables.Single(ta => !this.mapping.IsExtensionTable(ta));
            var tex = new TableExpression(new TableAlias(), entity, this.mapping.GetTableName(rootTable));
            aliases.Add(this.mapping.GetAlias(rootTable), tex.Alias);
            Expression source = tex;

            foreach (MappingTable table in tables.Where(t => this.mapping.IsExtensionTable(t)))
            {
                TableAlias joinedTableAlias = new TableAlias();
                string extensionAlias = this.mapping.GetAlias(table);
                aliases.Add(extensionAlias, joinedTableAlias);

                List<string> keyColumns = this.mapping.GetExtensionKeyColumnNames(table).ToList();
                List<MemberInfo> relatedMembers = this.mapping.GetExtensionRelatedMembers(table).ToList();
                string relatedAlias = this.mapping.GetExtensionRelatedAlias(table);

                TableAlias relatedTableAlias;
                aliases.TryGetValue(relatedAlias, out relatedTableAlias);

                TableExpression joinedTex = new TableExpression(joinedTableAlias, entity, this.mapping.GetTableName(table));

                Expression cond = null;
                for (int i = 0, n = keyColumns.Count; i < n; i++)
                {
                    var memberType = TypeHelper.GetMemberType(relatedMembers[i]);
                    var colType = this.GetColumnType(entity, relatedMembers[i]);
                    var relatedColumn = new ColumnExpression(memberType, colType, relatedTableAlias, this.mapping.GetColumnName(entity, relatedMembers[i]));
                    var joinedColumn = new ColumnExpression(memberType, colType, joinedTableAlias, keyColumns[i]);
                    var eq = joinedColumn.Equal(relatedColumn);
                    cond = (cond != null) ? cond.And(eq) : eq;
                }

                source = new JoinExpression(JoinType.SingletonLeftOuter, source, joinedTex, cond);
            }

            var columns = new List<ColumnDeclaration>();
            this.GetColumns(entity, aliases, columns);
            SelectExpression root = new SelectExpression(new TableAlias(), columns, source, null);
            var existingAliases = aliases.Values.ToArray();

            Expression projector = this.GetEntityExpression(root, entity);
            var selectAlias = new TableAlias();
            var pc = ColumnProjector.ProjectColumns(this.Translator.Linguist.Language, projector, null, selectAlias, root.Alias);
            var proj = new ProjectionExpression(
                new SelectExpression(selectAlias, pc.Columns, root, null),
                pc.Projector
                );

            return (ProjectionExpression)this.Translator.Police.ApplyPolicy(proj, entity.ElementType);
        }
        protected override Expression VisitProjection(ProjectionExpression projectionExpression)
        {
            var expression = (SqlExpression)Visit(projectionExpression.Expression);

            return(projectionExpression.Update(expression));
        }
Пример #59
0
        protected virtual Expression BuildExecuteBatch(BatchExpression batch)
        {
            Expression operation = this.Parameterize(batch.Operation.Body);

            var  cdu        = batch.Operation.Body as CDUCommandExpression;
            Type entityType = null;

            if (cdu != null)
            {
                entityType = cdu.Table.Mapping.EntityType;
            }

            string commandText = this.dbContext.BuildSql(operation);
            var    namedValues = NamedValueGatherer.Gather(operation);
            var    parameters  = namedValues.Select(v => new NamedParameter(v.Name, v.Type, v.SqlType)).ToArray();

            Expression[] values = namedValues.Select(v => Expression.Convert(this.Visit(v.Value), typeof(object))).ToArray();

            Expression paramSets = Expression.Call(typeof(Enumerable), "Select", new Type[] { batch.Operation.Parameters[1].Type, typeof(object[]) },
                                                   batch.Input,
                                                   Expression.Lambda(Expression.NewArrayInit(typeof(object), values), new[] { batch.Operation.Parameters[1] })
                                                   );

            Expression plan = null;

            ProjectionExpression projection = ProjectionFinder.FindProjection(operation);

            if (projection != null)
            {
                var saveScope = this.scope;
                ParameterExpression reader = Expression.Parameter(typeof(FieldReader), "r" + nReaders++);
                this.scope = new Scope(this.scope, reader, projection.Select.Alias, projection.Select.Columns);
                LambdaExpression projector = Expression.Lambda(this.Visit(projection.Projector), reader);
                this.scope = saveScope;

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

                var batchContext = Expression.New(typeof(BatchContext <>).MakeGenericType(projector.Body.Type).GetConstructors().FirstOrDefault(),
                                                  Expression.Constant(commandText),
                                                  Expression.Constant(parameters),
                                                  paramSets,
                                                  projector);
                plan = Expression.Call(this.executor, "Batch", new Type[] { projector.Body.Type }, batchContext);
            }
            else
            {
                var batchContext = Expression.New(typeof(BatchContext).GetConstructors().FirstOrDefault(),
                                                  Expression.Constant(commandText),
                                                  Expression.Constant(parameters),
                                                  paramSets,
                                                  Expression.Constant(entityType));

                //plan = Expression.Call(this.executor, "Batch", null,
                //    Expression.Constant(commandText),
                //    Expression.Constant(parameters),
                //    paramSets
                //    );
                plan = Expression.Call(this.executor, "Batch", null, batchContext);
            }

            return(plan);
        }
Пример #60
0
 private static bool IsNullableProjection(ProjectionExpression projection)
 => !(projection.Expression is ColumnExpression column) || column.IsNullable;