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)); }
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)); }
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)); }
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); }
/// <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); }
/// <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); }
/// <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)); }
/// <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())); }
/// <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); }
/// <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)); }
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)); }
/// <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); }
/// <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)); }
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); }
/// <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); }
/// <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))); }