private static Function CreateCollectionServiceOperation(string name, DataType type)
 {
     return(new Function(name)
     {
         ReturnType = DataTypes.CollectionType.WithElementDataType(type),
         Parameters =
         {
             new FunctionParameter("arg1", type),
             new FunctionParameter("arg2", type),
             new FunctionParameter("arg3", type),
         },
         Annotations =
         {
             new LegacyServiceOperationAnnotation()
             {
                 Method = HttpVerb.Get,
                 ReturnTypeQualifier = ServiceOperationReturnTypeQualifier.IEnumerable,
             },
             new FunctionBodyAnnotation()
             {
                 FunctionBody = LinqBuilder.AnonymousArray(
                     CommonQueryBuilder.FunctionParameterReference("arg1"),
                     CommonQueryBuilder.FunctionParameterReference("arg2"),
                     CommonQueryBuilder.FunctionParameterReference("arg3")),
             },
         }
     });
 }
        /// <summary>
        /// Resolves types for the specified expression.
        /// </summary>
        /// <param name="expression">The expression to resolve types for.</param>
        /// <returns>Expression with resolved types.</returns>
        public QueryExpression Visit(LinqNewInstanceExpression expression)
        {
            var constructorArguments = expression.ConstructorArguments.Select(this.ResolveTypes).ToList();
            var members = expression.Members.Select(this.ResolveTypes).ToList();

            return(LinqBuilder.NewInstance(constructorArguments, expression.MemberNames, members, expression.ExpressionType));
        }
Exemple #3
0
            public override PhpTypeCode Emit(LinqBuilder codeGenerator)
            {
                ILEmitter il = codeGenerator.IL;

                // NEW Func[object,object](<linq context>, <&lambda>);
                codeGenerator.EmitLoadLinqContext();
                il.Emit(OpCodes.Ldftn, codeGenerator.EmitLambda(string.Format("<Selector_{0}>",
                                                                              codeGenerator.GetNextSelectorNum()), valueVar, byExpr, PhpTypeCode.Object));
                il.Emit(OpCodes.Newobj, LinqExterns.Func2_object_object_ctor);

                DirectVarUse groupByVar = groupExpr as DirectVarUse;

                if ((groupByVar != null) && (groupByVar.VarName == valueVar.VarName))
                {
                    // LOAD Select[object,object](<source>, <delegate>);
                    // Simplified version - no element selector
                    il.Emit(OpCodes.Call, LinqExterns.GroupBy);
                }
                else
                {
                    // with element selector
                    codeGenerator.EmitLoadLinqContext();
                    il.Emit(OpCodes.Ldftn, codeGenerator.EmitLambda(string.Format("<Selector_{0}>",
                                                                                  codeGenerator.GetNextSelectorNum()), valueVar, groupExpr, PhpTypeCode.Object));
                    il.Emit(OpCodes.Newobj, LinqExterns.Func2_object_object_ctor);

                    il.Emit(OpCodes.Call, LinqExterns.GroupByElementSel);
                }

                // Conversion from IEnumerable<IGrouping<..>> to IEnumerable<object>
                il.Emit(OpCodes.Call, Methods.ClrObject_WrapRealObject);
                codeGenerator.CodeGenerator.EmitLoadClassContext();
                il.Emit(OpCodes.Call, Methods.Convert.ObjectToLinqSource);
                return(base.Emit(codeGenerator));
            }
Exemple #4
0
        internal static LinqLambdaExpression CreateLambda(QueryExpression source, IEnumerable <KeyValuePair <QueryProperty, QueryConstantExpression> > keys)
        {
            ExceptionUtilities.CheckArgumentNotNull(source, "source");
            ExceptionUtilities.CheckCollectionNotEmpty(keys, "keys");

            QueryType parameterType;

            if (source.ExpressionType.IsUnresolved)
            {
                parameterType = QueryType.Unresolved;
            }
            else
            {
                var queryCollectionType = source.ExpressionType as QueryCollectionType;
                ExceptionUtilities.CheckObjectNotNull(queryCollectionType, "Source expression type was not a collection. Type was: {0}", source.ExpressionType);
                parameterType = queryCollectionType.ElementType;
            }

            var parameter = LinqBuilder.Parameter(ParameterName, parameterType);

            // specifically using the overload of .Property which takes a type because it may have already been resolved and we don't want to throw that away
            var predicate = keys.Select(k => parameter.Property(k.Key.Name, k.Key.PropertyType).EqualTo(k.Value)).ToList();

            QueryExpression body = predicate[0];

            if (predicate.Count > 1)
            {
                for (int i = 1; i < predicate.Count; i++)
                {
                    body = CommonQueryBuilder.And(body, predicate[i]);
                }
            }

            return(LinqBuilder.Lambda(body, parameter));
        }
        /// <summary>
        /// Resolves types for the specified expression.
        /// </summary>
        /// <param name="expression">The expression to resolve types for.</param>
        /// <returns>Expression with resolved types.</returns>
        public QueryExpression Visit(LinqOrderByExpression expression)
        {
            var source       = this.ResolveTypes(expression.Source);
            var sourceType   = ValidateSourceIsACollection(source);
            var keySelectors = expression.KeySelectors.Select(s => this.ResolveLambdaTypes(s, sourceType)).ToArray();

            return(LinqBuilder.OrderBy(source, keySelectors, expression.AreDescending, sourceType));
        }
        /// <summary>
        /// Resolves types for the specified expression.
        /// </summary>
        /// <param name="expression">The expression to resolve types for.</param>
        /// <returns>Expression with resolved types.</returns>
        public QueryExpression Visit(LinqLambdaExpression expression)
        {
            var parameters = expression.Parameters.Select(this.ResolveTypes).Cast <LinqParameterExpression>().ToArray();
            var body       = this.ResolveTypes(expression.Body);
            var type       = new LinqLambdaType(body.ExpressionType, parameters.Select(p => p.ExpressionType), this.EvaluationStrategy);

            return(LinqBuilder.Lambda(body, parameters.ToArray(), type));
        }
Exemple #7
0
        internal override PhpTypeCode Emit(CodeGenerator /*!*/ codeGenerator)
        {
            LinqBuilder builder = codeGenerator.LinqBuilder;
            ILEmitter   il      = builder.IL;

            codeGenerator.EmitConversion(expression, PhpTypeCode.LinqSource);
            firstOp.Emit(builder);

            return(PhpTypeCode.LinqSource);
        }
Exemple #8
0
        /// <summary>
        /// Replaces the given expression.
        /// </summary>
        /// <param name="expression">The root node of the expression tree being visited.</param>
        /// <returns>Replaced expression.</returns>
        public virtual QueryExpression Visit(LinqNewExpression expression)
        {
            QueryExpression[] members = expression.Members.Select(this.ReplaceExpression).ToArray();
            if (HasChanged(expression.Members, members))
            {
                return(LinqBuilder.New(expression.MemberNames, members, expression.ExpressionType));
            }

            return(expression);
        }
Exemple #9
0
        /// <summary>
        /// Replaces the given expression.
        /// </summary>
        /// <param name="expression">The root node of the expression tree being visited.</param>
        /// <returns>Replaced expression.</returns>
        public virtual QueryExpression Visit(LinqNewInstanceExpression expression)
        {
            QueryExpression[] members = expression.Members.Select(this.ReplaceExpression).ToArray();
            QueryExpression[] constructorArguments = expression.ConstructorArguments.Select(this.ReplaceExpression).ToArray();
            if (HasChanged(expression.Members, members) || HasChanged(expression.ConstructorArguments, constructorArguments))
            {
                return(LinqBuilder.NewInstance(constructorArguments, expression.MemberNames, members, expression.ExpressionType));
            }

            return(expression);
        }
Exemple #10
0
 /// <summary>
 /// Emit next operation in the chain or nothing if next operation is null.
 /// To be used from inherited operations.
 /// </summary>
 public virtual PhpTypeCode Emit(LinqBuilder /*!*/ builder)
 {
     if (Next != null)
     {
         return(Next.Emit(builder));
     }
     else
     {
         return(PhpTypeCode.LinqSource);
     }
 }
        /// <summary>
        /// Resolves types for the specified expression.
        /// </summary>
        /// <param name="expression">The expression to resolve types for.</param>
        /// <returns>Expression with resolved types.</returns>
        public QueryExpression Visit(LinqNewExpression expression)
        {
            var members = expression.Members.Select(this.ResolveTypes).ToList();
            var type    = new QueryAnonymousStructuralType(this.EvaluationStrategy);

            for (int i = 0; i < members.Count; i++)
            {
                type.Add(QueryProperty.Create(expression.MemberNames[i], members[i].ExpressionType));
            }

            return(LinqBuilder.New(expression.MemberNames, members, type));
        }
Exemple #12
0
        /// <summary>
        /// Replaces the given expression.
        /// </summary>
        /// <param name="expression">The root node of the expression tree being visited.</param>
        /// <returns>Replaced expression.</returns>
        public virtual QueryExpression Visit(LinqLambdaExpression expression)
        {
            var             parameters = expression.Parameters.Select(this.ReplaceExpression).Cast <LinqParameterExpression>().ToArray();
            QueryExpression body       = this.ReplaceExpression(expression.Body);

            if (HasChanged(expression.Body, body) || HasChanged(expression.Parameters, parameters))
            {
                return(LinqBuilder.Lambda(body, parameters, expression.ExpressionType));
            }

            return(expression);
        }
        /// <summary>
        /// Resolves types for the specified expression.
        /// </summary>
        /// <param name="expression">The expression to resolve types for.</param>
        /// <returns>Expression with resolved types.</returns>
        public QueryExpression Visit(LinqJoinExpression expression)
        {
            var outer            = this.ResolveTypes(expression.Outer);
            var inner            = this.ResolveTypes(expression.Inner);
            var outerType        = ValidateSourceIsACollection(outer);
            var innerType        = ValidateSourceIsACollection(inner);
            var outerKeySelector = this.ResolveLambdaTypes(expression.OuterKeySelector, outerType);
            var innerKeySelector = this.ResolveLambdaTypes(expression.InnerKeySelector, innerType);

            var resultSelector = this.ResolveLambdaTypes(expression.ResultSelector, outerType, innerType);

            return(LinqBuilder.Join(outer, inner, outerKeySelector, innerKeySelector, resultSelector, resultSelector.Body.ExpressionType.CreateCollectionType()));
        }
Exemple #14
0
        /// <summary>
        /// Replaces the given expression.
        /// </summary>
        /// <param name="expression">The root node of the expression tree being visited.</param>
        /// <returns>Replaced expression.</returns>
        public virtual QueryExpression Visit(LinqOrderByExpression expression)
        {
            QueryExpression source = this.ReplaceExpression(expression.Source);

            var keySelectors = expression.KeySelectors.Select(this.ReplaceExpression).Cast <LinqLambdaExpression>().ToArray();

            if (HasChanged(expression.Source, source) || HasChanged(expression.KeySelectors, keySelectors))
            {
                // using internal overload, because there may be multiple keySelectors, public overloads only allow to set one at at time
                return(LinqBuilder.OrderBy(source, keySelectors, expression.AreDescending, expression.ExpressionType));
            }

            return(expression);
        }
Exemple #15
0
        /// <summary>
        /// Replaces the given expression.
        /// </summary>
        /// <param name="expression">The root node of the expression tree being visited.</param>
        /// <returns>
        /// Replaced expression.
        /// </returns>
        public override QueryExpression Visit(LinqSelectExpression expression)
        {
            // in a select, only properties will be sent
            this.propertyExpressions.Clear();
            expression.Lambda.Accept(this);

            if (this.propertyExpressions.Count == 0)
            {
                return(expression.Source);
            }

            var newExpression = LinqBuilder.New(this.propertyExpressions.Select(p => this.IdentifierGenerator.GenerateIdentifier("temp")), this.propertyExpressions);
            var lambda        = LinqBuilder.Lambda(newExpression, expression.Lambda.Parameters.ToArray());

            return(expression.Source.Select(lambda));
        }
Exemple #16
0
            public override PhpTypeCode Emit(LinqBuilder builder)
            {
                ILEmitter il = builder.IL;

                // source expected on stack

                // NEW Func[object,object](<linq context>, <&lambda>);
                builder.EmitLoadLinqContext();
                il.Emit(OpCodes.Ldftn, builder.EmitLambda(string.Format("<MultiSelector_{0}>",
                                                                        builder.GetNextMultiSelectorNum()), valueVar, innerChain, PhpTypeCode.LinqSource));
                il.Emit(OpCodes.Newobj, LinqExterns.Func2_object_IEnumerable_object_ctor);

                // LOAD Select[object,object](<source>, <delegate>);
                il.Emit(OpCodes.Call, LinqExterns.SelectMany);

                return(base.Emit(builder));
            }
Exemple #17
0
        /// <summary>
        /// Gets the existing values of the given primitive properties using the in-memory query evaluator
        /// </summary>
        /// <param name="set">The entity set</param>
        /// <param name="propertyNames">The properties to get values for</param>
        /// <returns>The values for the given properties as returned by the query evaluator</returns>
        protected internal Dictionary <string, List <object> > GetExistingPrimitivePropertyValues(EntitySet set, IEnumerable <string> propertyNames)
        {
            // build a projection query to find the values for the key properties
            var query = this.BuildRootQueryForSet(set).Select(o => LinqBuilder.New(propertyNames, propertyNames.Select(p => o.Property(p))));

            // evaluate the projection
            var collection = this.Evaluator.Evaluate(query) as QueryCollectionValue;

            ExceptionUtilities.CheckObjectNotNull(collection, "Query did not return a collection: {0}", query);
            ExceptionUtilities.Assert(collection.EvaluationError == null, "Query evaluation error: " + collection.EvaluationError);

            var structuralValues = collection.Elements.Cast <QueryStructuralValue>();
            var existingValues   = propertyNames
                                   .ToDictionary(p => p, p => structuralValues.Select(v => v.GetScalarValue(p).Value).ToList());

            return(existingValues);
        }
Exemple #18
0
            /// <summary>
            /// Emit lambda function that implements projection and call to
            /// IEnumerable.Select function (with current LINQ context as
            /// first and generated lambda as a second parameter)
            /// </summary>
            public override PhpTypeCode Emit(LinqBuilder /*!*/ builder)
            {
                ILEmitter il = builder.IL;

                // source expected on stack

                // NEW Func[object,object](<linq context>, <&lambda>);
                builder.EmitLoadLinqContext();
                il.Emit(OpCodes.Ldftn, builder.EmitLambda(string.Format("<Selector_{0}>",
                                                                        builder.GetNextSelectorNum()), valueVar, selector, PhpTypeCode.Object));
                il.Emit(OpCodes.Newobj, LinqExterns.Func2_object_object_ctor);

                // LOAD Select[object,object](<source>, <delegate>);
                il.Emit(OpCodes.Call, LinqExterns.Select);
                //il.Emit(OpCodes.Call, Methods.Operators.Select);

                return(base.Emit(builder));
            }
Exemple #19
0
        internal override PhpTypeCode Emit(CodeGenerator /*!*/ codeGenerator)
        {
            ILEmitter   il      = codeGenerator.IL;
            LinqBuilder builder = new LinqBuilder(codeGenerator);

            builder.DefineContextType();
            builder.EmitNewLinqContext();

            codeGenerator.LinqBuilder = builder;

            LinqOpChain chain    = body.BuildChain();
            var         typecode = chain.Emit(codeGenerator);

            // the result is IEnumerable<object>, let's wrap it and pass out
            il.Emit(OpCodes.Call, Methods.ClrObject_WrapRealObject);

            builder.BakeContextType();

            return(PhpTypeCode.Object);
        }
Exemple #20
0
        /// <summary>
        /// Ensures that the given parameter has a name and creates a new instance if not.
        /// </summary>
        /// <param name="expression">The expression.</param>
        /// <returns>Parameter with a name.</returns>
        /// <remarks>Subsequent calls to this method with the same expression
        /// will return the same instance of parameter.</remarks>
        public LinqParameterExpression EnsureParameterHasName(LinqParameterExpression expression)
        {
            LinqParameterExpression parameterWithName;

            if (!this.parameterMappings.TryGetValue(expression, out parameterWithName))
            {
                if (expression.Name == null)
                {
                    parameterWithName = LinqBuilder.Parameter(this.parameterNameGenerator.GenerateIdentifier("p"), expression.ExpressionType);
                }
                else
                {
                    parameterWithName = expression;
                }

                this.parameterMappings.Add(expression, parameterWithName);
            }

            return(parameterWithName);
        }
Exemple #21
0
            /// <summary>
            /// Emit lambda function that returns values used for sorting and
            /// call to OrderedSequence.OrderBy method (with current LINQ context as
            /// first and generated lambda as a second parameter)
            /// </summary>
            public override PhpTypeCode Emit(LinqBuilder codeGenerator)
            {
                ILEmitter il = codeGenerator.IL;

                // NEW Func[object,object](<linq context>, <&lambda>);
                codeGenerator.EmitLoadLinqContext();
                il.Emit(OpCodes.Ldftn, codeGenerator.EmitLambda(string.Format("<Comparer_{0}>",
                                                                              codeGenerator.GetNextComparerNum()), valueVar, expression, PhpTypeCode.Object));
                il.Emit(OpCodes.Newobj, LinqExterns.Func2_object_object_ctor);

                // LOAD Select[object,object](<source>, <delegate>);
                if (isThenBy)
                {
                    il.Emit(OpCodes.Call, ordering == Ordering.Descending ? LinqExterns.ThenByDescending : LinqExterns.ThenBy);
                }
                else
                {
                    il.Emit(OpCodes.Call, ordering == Ordering.Descending ? LinqExterns.OrderByDescending : LinqExterns.OrderBy);
                }

                return(base.Emit(codeGenerator));
            }
        private LinqLambdaExpression ResolveLambdaTypes(LinqLambdaExpression lambda, params QueryCollectionType[] parameterCollectionTypes)
        {
            ExceptionUtilities.Assert(lambda.Parameters.Count == parameterCollectionTypes.Length, "Lambda expression parameter numbers must match the length of parameterCollectionTypes.");

            for (int i = 0; i < lambda.Parameters.Count; i++)
            {
                var lambdaParameter = lambda.Parameters[i];
                this.parameterMappings.Add(lambdaParameter, LinqBuilder.Parameter(lambdaParameter.Name, parameterCollectionTypes[i].ElementType));
            }

            try
            {
                return((LinqLambdaExpression)this.ResolveTypes(lambda));
            }
            finally
            {
                foreach (var p in lambda.Parameters)
                {
                    this.parameterMappings.Remove(p);
                }
            }
        }
 /// <summary>
 /// Visits a QueryExpression tree whose root node is the LinqNewInstanceExpression.
 /// </summary>
 /// <param name="expression">The root node of the expression tree being visited.</param>
 /// <returns>Uri query string representing the expression.</returns>
 public override string Visit(LinqNewInstanceExpression expression)
 {
     return(this.Convert(LinqBuilder.New(expression.MemberNames, expression.Members)));
 }