/// <summary> /// Constructor with an <see cref="ConditionalExpression"/> and an <see cref="ExpressionConverter"/>. /// </summary> /// <param name="expression">The original, not serializable <see cref="Expression"/>.</param> /// <param name="expConverter">The <see cref="ExpressionConverter"/> to convert contained <see cref="Expression">Expressions</see>.</param> public SerializableConditionalExpression(ConditionalExpression expression, ExpressionConverter expConverter) : base(expression, expConverter) { IfTrue = expression.IfTrue.MakeSerializable(expConverter); IfFalse = expression.IfFalse.MakeSerializable(expConverter); Test = expression.Test.MakeSerializable(expConverter); }
/// <summary> /// Convert expression to code. /// </summary> /// <param name="expression">Expression.</param> /// <param name="converter">Expression converter.</param> /// <returns>Parts.</returns> public override ICode Convert(MethodCallExpression expression, ExpressionConverter converter) { var obj = converter.ConvertToObject(expression.Arguments[0]); var text = TowWaySqlSpec.ToStringFormat((string)obj); var array = expression.Arguments[1] as NewArrayExpression; return new StringFormatCode(text, array.Expressions.Select(e => converter.ConvertToCode(e)).ToArray()); }
/// <summary> /// Constructor with an <see cref="NewExpression"/> and an <see cref="ExpressionConverter"/>. /// </summary> /// <param name="expression">The original, not serializable <see cref="Expression"/>.</param> /// <param name="expConverter">The <see cref="ExpressionConverter"/> to convert contained <see cref="Expression">Expressions</see>.</param> public SerializableNewExpression(NewExpression expression, ExpressionConverter expConverter) : base(expression, expConverter) { Arguments = expression.Arguments.MakeSerializableCollection<SerializableExpression>(expConverter); Members = InterLinqTypeSystem.Instance.GetCollectionOf<InterLinqMemberInfo>(expression.Members); Constructor = InterLinqTypeSystem.Instance.GetInterLinqVersionOf<InterLinqConstructorInfo>(expression.Constructor); }
/// <summary> /// Constructor with an <see cref="MethodCallExpression"/> and an <see cref="ExpressionConverter"/>. /// </summary> /// <param name="expression">The original, not serializable <see cref="Expression"/>.</param> /// <param name="expConverter">The <see cref="ExpressionConverter"/> to convert contained <see cref="Expression">Expressions</see>.</param> public SerializableMethodCallExpression(MethodCallExpression expression, ExpressionConverter expConverter) : base(expression, expConverter) { Arguments = expression.Arguments.MakeSerializableCollection<SerializableExpression>(expConverter); Object = expression.Object.MakeSerializable(expConverter); Method = InterLinqTypeSystem.Instance.GetInterLinqVersionOf<InterLinqMethodInfo>(expression.Method); }
public void ctor_that_takes_expression_assigns_expression() { var converter = new ExpressionConverter(null); Assert.Null(converter.Expression); converter = new ExpressionConverter("null"); Assert.Equal("null", converter.Expression); }
/// <summary> /// Constructor with an <see cref="LambdaExpression"/> and an <see cref="ExpressionConverter"/>. /// </summary> /// <param name="expression">The original, not serializable <see cref="Expression"/>.</param> /// <param name="delegateType"><see cref="Type"/> of the delegate.</param> /// <param name="expConverter">The <see cref="ExpressionConverter"/> to convert contained <see cref="Expression">Expressions</see>.</param> public SerializableExpressionTyped(LambdaExpression expression, Type delegateType, ExpressionConverter expConverter) : base(expression, expConverter) { #if !NETFX_CORE Type = InterLinqTypeSystem.Instance.GetInterLinqVersionOf<InterLinqType>(delegateType); #else Type = InterLinqTypeSystem.Instance.GetInterLinqVersionOf<InterLinqType>(delegateType.GetTypeInfo()); #endif }
static ICode ConvertSelectedElement(ExpressionConverter converter, ObjectCreateMemberInfo element) { //single select. //for example, COUNT(*). if (string.IsNullOrEmpty(element.Name)) return converter.ConvertToCode(element.Expression); //normal select. return LineSpace(converter.ConvertToCode(element.Expression), "AS".ToCode(), element.Name.ToCode()); }
public void convert_value_evaluates_expression_to_obtain_value() { var converter = new ExpressionConverter(); converter.Expression = "2 * {0}"; Assert.Equal(10, converter.Convert(5, null, null, null)); Assert.Equal(-10, converter.Convert(-5, null, null, null)); Assert.Equal(10d, converter.Convert(5d, null, null, null)); }
public void convert_values_evaluates_expression_to_obtain_value() { var converter = new ExpressionConverter(); converter.Expression = "2 * {0} + {1} - {2}"; Assert.Equal(22, converter.Convert(new object[] { 10, 3, 1 }, null, null, null)); Assert.Equal(-22, converter.Convert(new object[] { -10, -3, -1 }, null, null, null)); Assert.Equal(22d, converter.Convert(new object[] { 10d, 3, 1 }, null, null, null)); }
/// <summary> /// Constructor with an <see cref="BinaryExpression"/> and an <see cref="ExpressionConverter"/>. /// </summary> /// <param name="expression">The original, not serializable <see cref="Expression"/>.</param> /// <param name="expConverter">The <see cref="ExpressionConverter"/> to convert contained <see cref="Expression">Expressions</see>.</param> public SerializableBinaryExpression(BinaryExpression expression, ExpressionConverter expConverter) : base(expression, expConverter) { Left = expression.Left.MakeSerializable(expConverter); Right = expression.Right.MakeSerializable(expConverter); Conversion = expression.Conversion.MakeSerializable<SerializableLambdaExpression>(expConverter); IsLiftedToNull = expression.IsLiftedToNull; Method = InterLinqTypeSystem.Instance.GetInterLinqVersionOf<InterLinqMethodInfo>(expression.Method); }
public void Should_convert_simple_expression_to_javascript_function() { var convert = new ExpressionConverter(); int a, b, c; a = b = c = 5; Expression<Func<int>> expression = () => a + b - c * a / b; var result = expression.Compile()(); string javascript = convert.Convert(expression); Assert.AreEqual("function() {a+b-c*a/b}", javascript); }
/// <summary> /// Constructor with an <see cref="ExpressionType"/>, a <see cref="Type"/> and an <see cref="ExpressionConverter"/>. /// </summary> /// <param name="nodeType">The <see cref="ExpressionType"/> of the <see cref="Expression"/>.</param> /// <param name="type">The <see cref="Type"/> of the <see cref="Expression"/>.</param> /// <param name="expConverter">The <see cref="ExpressionConverter"/> to convert contained <see cref="Expression">Expressions</see>.</param> private SerializableExpression(ExpressionType nodeType, Type type, ExpressionConverter expConverter) : this() { NodeType = nodeType; #if !NETFX_CORE Type = InterLinqTypeSystem.Instance.GetInterLinqVersionOf<InterLinqType>(type); #else Type = InterLinqTypeSystem.Instance.GetInterLinqVersionOf<InterLinqType>(type.GetTypeInfo()); #endif }
/// <summary> /// Constructor with an <see cref="TypeBinaryExpression"/> and an <see cref="ExpressionConverter"/>. /// </summary> /// <param name="expression">The original, not serializable <see cref="Expression"/>.</param> /// <param name="expConverter">The <see cref="ExpressionConverter"/> to convert contained <see cref="Expression">Expressions</see>.</param> public SerializableTypeBinaryExpression(TypeBinaryExpression expression, ExpressionConverter expConverter) : base(expression, expConverter) { Expression = expression.Expression.MakeSerializable(expConverter); #if !NETFX_CORE TypeOperand = InterLinqTypeSystem.Instance.GetInterLinqVersionOf<InterLinqType>(expression.TypeOperand); #else TypeOperand = InterLinqTypeSystem.Instance.GetInterLinqVersionOf<InterLinqType>(expression.TypeOperand.GetTypeInfo()); #endif }
public void Now_something_a_bit_more_advanced() { var convert = new ExpressionConverter(); var fieldService = new FieldService(); convert.MapToArray("fieldService.GetField", "felter"); Expression<Func<Field>> bodyExpr = () => fieldService.GetField(123); string javascript = convert.Convert(bodyExpr); File.WriteAllText(@"c:\temp\Now_something_a_bit_more_advanced.js", string.Format("var foo = {0};", javascript)); Assert.IsNotNull(javascript); }
/// <summary> /// Convert expression to code. /// </summary> /// <param name="expression">Expression.</param> /// <param name="converter">Expression converter.</param> /// <returns>Parts.</returns> public override ICode Convert(MethodCallExpression expression, ExpressionConverter converter) { //ALL, DISTINCT, TOP int expressionIndex = expression.SkipMethodChain(0); var selectParts = new ICode[expression.Arguments.Count - expressionIndex]; selectParts[0] = SelectClause; for (int i = 0; i < selectParts.Length - 1; i++, expressionIndex++) { selectParts[i + 1] = converter.ConvertToCode(expression.Arguments[expressionIndex]); } var select = LineSpace(selectParts); //select elemnts. var selectTargets = expression.Arguments[expression.Arguments.Count - 1]; //* if (typeof(IAsterisk).IsAssignableFromEx(selectTargets.Type)) { select.Add("*".ToCode()); return new SelectClauseCode(select); } //new []{ a, b, c} recursive. else if (selectTargets.Type.IsArray) { var newArrayExp = selectTargets as NewArrayExpression; var array = new ICode[newArrayExp.Expressions.Count]; for (int i = 0; i < array.Length; i++) { array[i] = converter.ConvertToCode(newArrayExp.Expressions[i]); } var coreCode = new VCode(select, new VCode(array) { Indent = 1, Separator = "," }); return new SelectClauseCode(coreCode); } //new { item = db.tbl.column } else { var createInfo = ObjectCreateAnalyzer.MakeSelectInfo(selectTargets); var elements = new ICode[createInfo.Members.Length]; for (int i = 0; i < elements.Length; i++) { elements[i] = ConvertSelectedElement(converter, createInfo.Members[i]); } var coreCode = new VCode(select, new VCode(elements) { Indent = 1, Separator = "," }); return new SelectClauseCode(coreCode); } }
/// <summary> /// Constructor with an <see cref="ConstantExpression"/> and an <see cref="ExpressionConverter"/>. /// </summary> /// <param name="expression">The original, not serializable <see cref="Expression"/>.</param> /// <param name="expConverter">The <see cref="ExpressionConverter"/> to convert contained <see cref="Expression">Expressions</see>.</param> public SerializableConstantExpression(ConstantExpression expression, ExpressionConverter expConverter) : base(expression, expConverter) { if (expression.Value != null && expression.Value is InterLinqQueryBase) { // Handle normal Query<> object Value = expression.Value; } else { // Compile variable into expression LambdaExpression lambda = Expression.Lambda(expression); Delegate fn = lambda.Compile(); Value = Expression.Constant(fn.DynamicInvoke(null), expression.Type).Value; } }
internal IEnumerable<ICode> InitAndConvertArguments(MethodCallExpression expression, ExpressionConverter converter) { lock (this) { if (string.IsNullOrEmpty(Name)) Name = expression.Method.Name.ToUpper(); if (NameCode == null) NameCode = Name.ToCode(); if (_startIndex == -1) _startIndex = expression.SkipMethodChain(0); if (_isParamArray == null) { var paramsInfo = expression.Method.GetParameters(); _isParamArray = new bool[paramsInfo.Length]; for (int i = 0; i < paramsInfo.Length; i++) { _isParamArray[i] = paramsInfo[i].GetAttribute<ParamArrayAttribute>() != null; } } } var args = new List<ICode>(); for (int i = _startIndex; i < expression.Arguments.Count; i++) { var argExp = expression.Arguments[i]; if (_isParamArray[i]) { var newArrayExp = argExp as NewArrayExpression; if (newArrayExp != null) { foreach (var e in newArrayExp.Expressions) args.Add(converter.ConvertToCode(e)); } else { var obj = converter.ConvertToObject(argExp); foreach (var e in (IEnumerable)obj) args.Add(converter.ConvertToCode(e)); } } else { args.Add(converter.ConvertToCode(argExp)); } } return args; }
/// <summary> /// Constructor with an <see cref="LambdaExpression"/> and an <see cref="ExpressionConverter"/>. /// </summary> /// <param name="expression">The original, not serializable <see cref="Expression"/>.</param> /// <param name="delegateType"><see cref="Type"/> of the delegate.</param> /// <param name="expConverter">The <see cref="ExpressionConverter"/> to convert contained <see cref="Expression">Expressions</see>.</param> public SerializableExpressionTyped(LambdaExpression expression, Type delegateType, ExpressionConverter expConverter) : base(expression, expConverter) { Type = InterLinqTypeSystem.Instance.GetInterLinqVersionOf<InterLinqType>(delegateType); }
/// <summary> /// Constructor with an <see cref="ExpressionType"/>, a <see cref="Type"/> and an <see cref="ExpressionConverter"/>. /// </summary> /// <param name="nodeType">The <see cref="ExpressionType"/> of the <see cref="Expression"/>.</param> /// <param name="type">The <see cref="Type"/> of the <see cref="Expression"/>.</param> /// <param name="expConverter">The <see cref="ExpressionConverter"/> to convert contained <see cref="Expression">Expressions</see>.</param> private SerializableExpression(ExpressionType nodeType, Type type, ExpressionConverter expConverter) : this() { NodeType = nodeType; Type = InterLinqTypeSystem.Instance.GetInterLinqVersionOf<InterLinqType>(type); }
public static double CalculateExpression(List <Token> mathTokensExpression) { Stack <Token> postfixExpresion = ExpressionConverter.GetPostfixExpression(mathTokensExpression); Stack <Token> variablesStack = new Stack <Token>(); while (postfixExpresion.Count > 0) { Token token = postfixExpresion.Pop(); switch (token.Type) { case TOKEN_TYPE.VARIABLE: { variablesStack.Push(token); break; } case TOKEN_TYPE.CONST: { token.Value = ConstManager.GetConstByToken(token).Value.ToString(); variablesStack.Push(token); break; } case TOKEN_TYPE.UNARY_OPERATION: { Token variable; double var; try { variable = variablesStack.Pop(); var = double.Parse(variable.Value); } catch (Exception) { throw new Exception("Bad expression"); } switch (token.Value) { case "-": { var *= -1; break; } case "+": { break; } case "sqrt": { if (var < 0) { throw new Exception("Do not extract the sqrt of a negative number"); } var = Math.Sqrt(var); break; } case "not": { if (var != 0 && var != 1) { throw new Exception("Not boolean operand for \"" + token.Value + "\""); } var = var == 0 ? 1 : 0; break; } case "!": { double n = var; var = 1; for (int i = 2; i <= n; i++) { var *= i; } break; } case "sin": { var = Math.Sin(var); break; } case "cos": { var = Math.Cos(var); break; } case "tg": { var = Math.Tan(var); break; } case "ctg": { var = Math.Cos(var) / Math.Sin(var); break; } case "log": { var = Math.Log(var); break; } default: { throw new Exception("Undefined unary operator"); } } variable.Value = var.ToString(); variablesStack.Push(variable); break; } case TOKEN_TYPE.BINARY_OPERATION: { Token secondVar; Token firstVar; try { secondVar = variablesStack.Pop(); firstVar = variablesStack.Pop(); } catch (Exception) { throw new Exception("Bad expression"); } double firstDouble, secondDouble; try { firstDouble = double.Parse(firstVar.Value); secondDouble = double.Parse(secondVar.Value); } catch (Exception) { throw new Exception("Bad variable syntax"); } Token newVar = new Token(); newVar.Type = TOKEN_TYPE.VARIABLE; switch (token.Value) { case "+": { newVar.Value = (firstDouble + secondDouble).ToString(); break; } case "-": { newVar.Value = (firstDouble - secondDouble).ToString(); break; } case "*": { newVar.Value = (firstDouble * secondDouble).ToString(); break; } case "/": { if (secondDouble == 0) { throw new Exception("Сannot be divided by zero"); } newVar.Value = (firstDouble / secondDouble).ToString(); break; } case "%": { newVar.Value = (firstDouble % secondDouble).ToString(); break; } case "^": { newVar.Value = Math.Pow(firstDouble, secondDouble).ToString(); break; } case "and": { newVar.Value = ((int)secondDouble & (int)firstDouble).ToString(); break; } case "or": { newVar.Value = ((int)secondDouble | (int)firstDouble).ToString(); break; } case "xor": { newVar.Value = ((int)secondDouble ^ (int)firstDouble).ToString(); break; } case ">>": { newVar.Value = ((int)firstDouble >> (int)secondDouble).ToString(); break; } case "<<": { newVar.Value = ((int)firstDouble << (int)secondDouble).ToString(); break; } case "||": { if ((firstDouble != 0 && firstDouble != 1) || (secondDouble != 0 && secondDouble != 1)) { throw new Exception("Not boolean operands for \"||\""); } bool firstBool = firstDouble == 0 ? false : true; bool secondBool = secondDouble == 0 ? false : true; newVar.Value = (firstBool || secondBool == true ? 1 : 0).ToString(); break; } case "&&": { if (firstDouble != 0 && firstDouble != 1 || secondDouble != 0 && secondDouble != 1) { throw new Exception("No boolean operands for \"" + token.Value + "\""); } bool firstBool = firstDouble == 0 ? false : true; bool secondBool = secondDouble == 0 ? false : true; newVar.Value = (firstBool && secondBool == true ? 1 : 0).ToString(); break; } case ">": { newVar.Value = (firstDouble > secondDouble ? 1 : 0).ToString(); break; } case ">=": { newVar.Value = (firstDouble >= secondDouble ? 1 : 0).ToString(); break; } case "<": { newVar.Value = (firstDouble < secondDouble ? 1 : 0).ToString(); break; } case "<=": { newVar.Value = (firstDouble <= secondDouble ? 1 : 0).ToString(); break; } case "==": { newVar.Value = (firstDouble == secondDouble ? 1 : 0).ToString(); break; } case "!=": { newVar.Value = (firstDouble != secondDouble ? 1 : 0).ToString(); break; } default: { throw new Exception("Undefined binary operator"); } } variablesStack.Push(newVar); break; } default: { throw new Exception("Bad expression"); } } } if (variablesStack.Count != 1) { throw new Exception("Bad expression"); } return(double.Parse(variablesStack.Pop().Value)); }
/// <summary> /// Constructor with an <see cref="ElementInit"/> and an <see cref="ExpressionConverter"/>. /// </summary> /// <param name="elementInit">The original, not serializable <see cref="ElementInit"/>.</param> /// <param name="expConverter">The <see cref="ExpressionConverter"/> to convert contained <see cref="Expression">Expressions</see>.</param> public SerializableElementInit(ElementInit elementInit, ExpressionConverter expConverter) { Arguments = elementInit.Arguments.MakeSerializableCollection<SerializableExpression>(expConverter); AddMethod = elementInit.AddMethod; }
public void Offset(System.Linq.Expressions.Expression <Func <T, int> > expression) => Offset(ExpressionConverter.Convert(expression));
/// <summary> /// Constructor with an <see cref="ExpressionType"/>, a <see cref="Type"/> and an <see cref="ExpressionConverter"/>. /// </summary> /// <param name="nodeType">The <see cref="ExpressionType"/> of the <see cref="Expression"/>.</param> /// <param name="type">The <see cref="Type"/> of the <see cref="Expression"/>.</param> /// <param name="expConverter">The <see cref="ExpressionConverter"/> to convert contained <see cref="Expression">Expressions</see>.</param> // ReSharper disable UnusedParameter.Local private SerializableExpression(ExpressionType nodeType, Type type, ExpressionConverter expConverter) : this() { NodeType = nodeType; Type = InterLinqTypeSystem.Instance.GetInterLinqVersionOf <InterLinqType>(type); }
/// <summary> /// Constructor with an <see cref="MemberMemberBinding"/> and an <see cref="ExpressionConverter"/>. /// </summary> /// <param name="memberMemberBinding">The original, not serializable <see cref="MemberBinding"/>.</param> /// <param name="expConverter">The <see cref="ExpressionConverter"/> to convert contained <see cref="Expression">Expressions</see>.</param> public SerializableMemberMemberBinding(MemberMemberBinding memberMemberBinding, ExpressionConverter expConverter) : base(memberMemberBinding, expConverter) { Bindings = expConverter.ConvertToSerializableObjectCollection<SerializableMemberBinding>(memberMemberBinding.Bindings); }
internal override ObjectQueryExecutionPlan GetExecutionPlan(MergeOption?forMergeOption) { Debug.Assert(this.Span == null, "Include span specified on compiled LINQ-based ObjectQuery instead of within the expression tree?"); Debug.Assert(this._cachedPlan == null, "Cached plan should not be set on compiled LINQ queries"); // Metadata is required to generate the execution plan or to retrieve it from the cache. this.ObjectContext.EnsureMetadata(); ObjectQueryExecutionPlan plan = null; CompiledQueryCacheEntry cacheEntry = this._cacheEntry; bool useCSharpNullComparisonBehavior = this.ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior; if (cacheEntry != null) { // The cache entry has already been retrieved, so compute the effective merge option with the following precedence: // 1. The merge option specified as the argument to Execute(MergeOption), and so to this method // 2. The merge option set using ObjectQuery.MergeOption // 3. The propagated merge option as recorded in the cache entry // 4. The global default merge option. MergeOption mergeOption = EnsureMergeOption(forMergeOption, this.UserSpecifiedMergeOption, cacheEntry.PropagatedMergeOption); // Ask for the corresponding execution plan plan = cacheEntry.GetExecutionPlan(mergeOption, useCSharpNullComparisonBehavior); if (plan == null) { // Convert the LINQ expression to produce a command tree ExpressionConverter converter = this.CreateExpressionConverter(); DbExpression queryExpression = converter.Convert(); ReadOnlyCollection <KeyValuePair <ObjectParameter, QueryParameterExpression> > parameters = converter.GetParameters(); // Prepare the execution plan using the command tree and the computed effective merge option DbQueryCommandTree tree = DbQueryCommandTree.FromValidExpression(this.ObjectContext.MetadataWorkspace, DataSpace.CSpace, queryExpression); plan = ObjectQueryExecutionPlan.Prepare(this.ObjectContext, tree, this.ElementType, mergeOption, converter.PropagatedSpan, parameters, converter.AliasGenerator); // Update and retrieve the execution plan plan = cacheEntry.SetExecutionPlan(plan, useCSharpNullComparisonBehavior); } } else { // This instance does not yet have a reference to a cache entry. // First, attempt to retrieve an existing cache entry. QueryCacheManager cacheManager = this.ObjectContext.MetadataWorkspace.GetQueryCacheManager(); CompiledQueryCacheKey cacheKey = new CompiledQueryCacheKey(this._cacheToken); if (cacheManager.TryCacheLookup(cacheKey, out cacheEntry)) { // An entry was found in the cache, so compute the effective merge option based on its propagated merge option, // and use the UseCSharpNullComparisonBehavior flag to retrieve the corresponding execution plan. this._cacheEntry = cacheEntry; MergeOption mergeOption = EnsureMergeOption(forMergeOption, this.UserSpecifiedMergeOption, cacheEntry.PropagatedMergeOption); plan = cacheEntry.GetExecutionPlan(mergeOption, useCSharpNullComparisonBehavior); } // If no cache entry was found or if the cache entry did not contain the required execution plan, the plan is still null at this point. if (plan == null) { // The execution plan needs to be produced, so create an appropriate expression converter and generate the query command tree. ExpressionConverter converter = this.CreateExpressionConverter(); DbExpression queryExpression = converter.Convert(); ReadOnlyCollection <KeyValuePair <ObjectParameter, QueryParameterExpression> > parameters = converter.GetParameters(); DbQueryCommandTree tree = DbQueryCommandTree.FromValidExpression(this.ObjectContext.MetadataWorkspace, DataSpace.CSpace, queryExpression); // If a cache entry for this compiled query's cache key was not successfully retrieved, then it must be created now. // Note that this is only possible after converting the LINQ expression and discovering the propagated merge option, // which is required in order to create the cache entry. if (cacheEntry == null) { // Create the cache entry using this instance's cache token and the propagated merge option (which may be null) cacheEntry = new CompiledQueryCacheEntry(cacheKey, converter.PropagatedMergeOption); // Attempt to add the entry to the cache. If an entry was added in the meantime, use that entry instead. QueryCacheEntry foundEntry; if (cacheManager.TryLookupAndAdd(cacheEntry, out foundEntry)) { cacheEntry = (CompiledQueryCacheEntry)foundEntry; } // We now have a cache entry, so hold onto it for future use. this._cacheEntry = cacheEntry; } // Recompute the effective merge option in case a cache entry was just constructed above MergeOption mergeOption = EnsureMergeOption(forMergeOption, this.UserSpecifiedMergeOption, cacheEntry.PropagatedMergeOption); // Ask the (retrieved or constructed) cache entry for the corresponding execution plan. plan = cacheEntry.GetExecutionPlan(mergeOption, useCSharpNullComparisonBehavior); if (plan == null) { // The plan is not present, so prepare it now using the computed effective merge option plan = ObjectQueryExecutionPlan.Prepare(this.ObjectContext, tree, this.ElementType, mergeOption, converter.PropagatedSpan, parameters, converter.AliasGenerator); // Update the execution plan on the cache entry. // If the execution plan was set in the meantime, SetExecutionPlan will return that value, otherwise it will return 'plan'. plan = cacheEntry.SetExecutionPlan(plan, useCSharpNullComparisonBehavior); } } } // Get parameters from the plan and set them. ObjectParameterCollection currentParams = this.EnsureParameters(); if (plan.CompiledQueryParameters != null && plan.CompiledQueryParameters.Count > 0) { currentParams.SetReadOnly(false); currentParams.Clear(); foreach (KeyValuePair <ObjectParameter, QueryParameterExpression> pair in plan.CompiledQueryParameters) { // Parameters retrieved from the CompiledQueryParameters collection must be cloned before being added to the query. // The cached plan is shared and when used in multithreaded scenarios failing to clone the parameter would result // in the code below updating the values of shared parameter instances saved in the cached plan and used by all // queries using that plan, regardless of the values they were actually invoked with, causing incorrect results // when those queries were later executed. // ObjectParameter convertedParam = pair.Key.ShallowCopy(); QueryParameterExpression parameterExpression = pair.Value; currentParams.Add(convertedParam); if (parameterExpression != null) { convertedParam.Value = parameterExpression.EvaluateParameter(_parameterValues); } } } currentParams.SetReadOnly(true); Debug.Assert(plan != null, "Failed to produce an execution plan?"); return(plan); }
/// <summary> /// Constructor with an <see cref="LambdaExpression"/> and an <see cref="ExpressionConverter"/>. /// </summary> /// <param name="expression">The original, not serializable <see cref="Expression"/>.</param> /// <param name="delegateType"><see cref="Type"/> of the delegate.</param> /// <param name="expConverter">The <see cref="ExpressionConverter"/> to convert contained <see cref="Expression">Expressions</see>.</param> public SerializableExpressionTyped(LambdaExpression expression, Type delegateType, ExpressionConverter expConverter) : base(expression, expConverter) { Type = InterLinqTypeSystem.Instance.GetInterLinqVersionOf <InterLinqType>(delegateType); }
/// <summary> /// Constructor with an <see cref="Expression"/> and an <see cref="ExpressionConverter"/>. /// </summary> /// <param name="expression">The original, not serializable <see cref="Expression"/>.</param> /// <param name="expConverter">The <see cref="ExpressionConverter"/> to convert contained <see cref="Expression">Expressions</see>.</param> protected SerializableExpression(Expression expression, ExpressionConverter expConverter) : this(expression.NodeType, expression.Type, expConverter) { HashCode = expression.GetHashCode(); }
/// <summary> /// Constructor with an <see cref="ListInitExpression"/> and an <see cref="ExpressionConverter"/>. /// </summary> /// <param name="expression">The original, not serializable <see cref="Expression"/>.</param> /// <param name="expConverter">The <see cref="ExpressionConverter"/> to convert contained <see cref="Expression">Expressions</see>.</param> public SerializableListInitExpression(ListInitExpression expression, ExpressionConverter expConverter) : base(expression, expConverter) { NewExpression = expression.NewExpression.MakeSerializable <SerializableNewExpression>(expConverter); Initializers = expConverter.ConvertToSerializableObjectCollection <SerializableElementInit>(expression.Initializers); }
/// <summary> /// Constructor with an <see cref="MemberListBinding"/> and an <see cref="ExpressionConverter"/>. /// </summary> /// <param name="memberListBinding">The original, not serializable <see cref="MemberBinding"/>.</param> /// <param name="expConverter">The <see cref="ExpressionConverter"/> to convert contained <see cref="Expression">Expressions</see>.</param> public SerializableMemberListBinding(MemberListBinding memberListBinding, ExpressionConverter expConverter) : base(memberListBinding, expConverter) { Initializers = expConverter.ConvertToSerializableObjectCollection <SerializableElementInit>(memberListBinding.Initializers); }
/// <summary> /// Converts an expression to an expression node. /// </summary> /// <param name="expression">The expression.</param> /// <param name="factorySettings">The factory settings to use.</param> /// <returns></returns> public static ExpressionNode ToExpressionNode(this Expression expression, FactorySettings factorySettings = null) { var converter = new ExpressionConverter(); return(converter.Convert(expression, factorySettings)); }
/// <summary> /// Constructor with an <see cref="MemberBinding"/> and an <see cref="ExpressionConverter"/>. /// </summary> /// <param name="memberBinding">The original, not serializable <see cref="MemberBinding"/>.</param> /// <param name="expConverter">The <see cref="ExpressionConverter"/> to convert contained <see cref="Expression">Expressions</see>.</param> protected SerializableMemberBinding(MemberBinding memberBinding, ExpressionConverter expConverter) { Member = memberBinding.Member; BindingType = memberBinding.BindingType; }
public void Teardown() { expressionConverter = null; tokenizer = null; parser = null; }
/// <summary> /// Constructor with an <see cref="MemberAssignment"/> and an <see cref="ExpressionConverter"/>. /// </summary> /// <param name="memberAssignment">The original, not serializable <see cref="MemberBinding"/>.</param> /// <param name="expConverter">The <see cref="ExpressionConverter"/> to convert contained <see cref="Expression">Expressions</see>.</param> public SerializableMemberAssignment(MemberAssignment memberAssignment, ExpressionConverter expConverter) : base(memberAssignment, expConverter) { Expression = memberAssignment.Expression.MakeSerializable(expConverter); }
public void DescribeClrType_returns_full_name_for_normal_types() { Assert.Equal("System.Data.Entity.Core.Objects.ELinq.ExpressionConverterTests", ExpressionConverter.DescribeClrType(GetType())); Assert.Equal( "System.Data.Entity.Core.Objects.ELinq.ExpressionConverterTests+ANest", ExpressionConverter.DescribeClrType(typeof(ANest))); }
public override ICode Convert(MethodCallExpression expression, ExpressionConverter converter) => converter.ConvertToCode(expression.Arguments[0]);
/// <summary> /// Extension Method for <see cref="Expression"/>. /// Converts an <see cref="Expression"/> to a <see cref="SerializableExpression"/>. /// </summary> /// <param name="exp">Extended class instance.</param> /// <param name="expConverter"><see cref="ExpressionConverter"/> instance.</param> /// <returns>Returns the converted <see cref="SerializableExpression"/>.</returns> public static SerializableExpression MakeSerializable(this Expression exp, ExpressionConverter expConverter) { return(expConverter.Convert(exp)); }
/// <summary> /// Constructor with an <see cref="ParameterExpression"/> and an <see cref="ExpressionConverter"/>. /// </summary> /// <param name="expression">The original, not serializable <see cref="Expression"/>.</param> /// <param name="expConverter">The <see cref="ExpressionConverter"/> to convert contained <see cref="Expression">Expressions</see>.</param> public SerializableParameterExpression(ParameterExpression expression, ExpressionConverter expConverter) : base(expression, expConverter) { Name = expression.Name; }
/// <summary> /// Extension Method for <see cref="Expression"/>. /// Converts an <see cref="Expression"/> to a <typeparamref name="T"/>. /// </summary> /// <typeparam name="T">Return type (must be subclass of <see cref="SerializableExpression"/>.</typeparam> /// <param name="exp">Extended class instance.</param> /// <param name="expConverter"><see cref="ExpressionConverter"/> instance.</param> /// <returns>Returns the converted <typeparamref name="T"/>.</returns> public static T MakeSerializable <T>(this Expression exp, ExpressionConverter expConverter) where T : SerializableExpression { return(expConverter.Convert <T>(exp)); }
internal IEnumerable <ICode> InitAndConvertArguments(MethodCallExpression expression, ExpressionConverter converter) { lock (this) { if (string.IsNullOrEmpty(Name)) { Name = expression.Method.Name.ToUpper(); } if (NameCode == null) { NameCode = Name.ToCode(); } if (_startIndex == -1) { _startIndex = expression.SkipMethodChain(0); } if (_isParamArray == null) { var paramsInfo = expression.Method.GetParameters(); _isParamArray = new bool[paramsInfo.Length]; for (int i = 0; i < paramsInfo.Length; i++) { _isParamArray[i] = paramsInfo[i].GetAttribute <ParamArrayAttribute>() != null; } } } var args = new List <ICode>(); for (int i = _startIndex; i < expression.Arguments.Count; i++) { var argExp = expression.Arguments[i]; if (_isParamArray[i]) { var newArrayExp = argExp as NewArrayExpression; if (newArrayExp != null) { bool isEmpty = true; foreach (var e in newArrayExp.Expressions) { var argCode = converter.ConvertToCode(e); if (isEmpty) { isEmpty = argCode.IsEmpty; } args.Add(argCode); } if (VanishIfEmptyParams && isEmpty) { return(null); } } else { var obj = converter.ConvertToObject(argExp); foreach (var e in (IEnumerable)obj) { args.Add(converter.ConvertToCode(e)); } } } else { args.Add(converter.ConvertToCode(argExp)); } } return(args); }
/// <summary> /// Extension Method for <see cref="IEnumerable"/>. /// Converts an <see cref="IEnumerable"/> to a <see cref="ReadOnlyCollection{T}"/>. /// </summary> /// <typeparam name="T">Return type (must be subclass of <see cref="SerializableExpression"/>.</typeparam> /// <param name="exp">Extended class instance.</param> /// <param name="expConverter"><see cref="ExpressionConverter"/> instance.</param> /// <returns>Returns the converted <see cref="ReadOnlyCollection{T}"/>.</returns> public static ReadOnlyCollection <T> MakeSerializableCollection <T>(this IEnumerable exp, ExpressionConverter expConverter) where T : SerializableExpression { return(expConverter.ConvertCollection <T>(exp)); }
/// <summary> /// Constructor with an <see cref="MemberListBinding"/> and an <see cref="ExpressionConverter"/>. /// </summary> /// <param name="memberListBinding">The original, not serializable <see cref="MemberBinding"/>.</param> /// <param name="expConverter">The <see cref="ExpressionConverter"/> to convert contained <see cref="Expression">Expressions</see>.</param> public SerializableMemberListBinding(MemberListBinding memberListBinding, ExpressionConverter expConverter) : base(memberListBinding, expConverter) { Initializers = expConverter.ConvertToSerializableObjectCollection<SerializableElementInit>(memberListBinding.Initializers); }
/// <summary> /// Constructor with an <see cref="TypeBinaryExpression"/> and an <see cref="ExpressionConverter"/>. /// </summary> /// <param name="expression">The original, not serializable <see cref="Expression"/>.</param> /// <param name="expConverter">The <see cref="ExpressionConverter"/> to convert contained <see cref="Expression">Expressions</see>.</param> public SerializableTypeBinaryExpression(TypeBinaryExpression expression, ExpressionConverter expConverter) : base(expression, expConverter) { Expression = expression.Expression.MakeSerializable(expConverter); TypeOperand = InterLinqTypeSystem.Instance.GetInterLinqVersionOf<InterLinqType>(expression.TypeOperand); }
/// <summary> /// Convert expression to code. /// </summary> /// <param name="expression">Expression.</param> /// <param name="converter">Expression converter.</param> /// <returns>Parts.</returns> public override ICode Convert(NewExpression expression, ExpressionConverter converter) { var obj = converter.ConvertToObject(expression.Arguments[0]); return (bool)obj ? converter.ConvertToCode(expression.Arguments[1]) : string.Empty.ToCode(); }
public void GroupBy <TProperty>(System.Linq.Expressions.Expression <Func <T, TProperty> > expression) => GroupBy(ExpressionConverter.Convert(expression));
/// <summary> /// Convert expression to code. /// </summary> /// <param name="expression">Expression.</param> /// <param name="converter">Expression converter.</param> /// <returns>Parts.</returns> public override ICode Convert(NewExpression expression, ExpressionConverter converter) { var obj = converter.ConvertToObject(expression.Arguments[0]); return((bool)obj ? (ICode) new AroundCode(converter.ConvertToCode(expression.Arguments[1]), "(", ")") : string.Empty.ToCode()); }
/// <summary> /// Constructor with an <see cref="MemberExpression"/> and an <see cref="ExpressionConverter"/>. /// </summary> /// <param name="expression">The original, not serializable <see cref="Expression"/>.</param> /// <param name="expConverter">The <see cref="ExpressionConverter"/> to convert contained <see cref="Expression">Expressions</see>.</param> public SerializableMemberExpression(MemberExpression expression, ExpressionConverter expConverter) : base(expression, expConverter) { Expression = expression.Expression.MakeSerializable(expConverter); Member = InterLinqTypeSystem.Instance.GetInterLinqMemberInfo(expression.Member); }
/// <summary> /// Convert expression to code. /// </summary> /// <param name="expression">Expression.</param> /// <param name="converter">Expression converter.</param> /// <returns>Parts.</returns> public override ICode Convert(MethodCallExpression expression, ExpressionConverter converter) { var arry = expression.Arguments[0] as NewArrayExpression; return(ConvertNormalWith(converter, arry)); }
internal override ObjectQueryExecutionPlan GetExecutionPlan(MergeOption?forMergeOption) { Debug.Assert(this.Span == null, "Include span specified on compiled LINQ-based ObjectQuery instead of within the expression tree?"); // If this query has already been prepared, its current execution plan may no longer be valid. ObjectQueryExecutionPlan plan = this._cachedPlan; if (plan != null) { // Was a merge option specified in the call to Execute(MergeOption) or set via ObjectQuery.MergeOption? MergeOption?explicitMergeOption = GetMergeOption(forMergeOption, this.UserSpecifiedMergeOption); // If a merge option was explicitly specified, and it does not match the plan's merge option, then the plan is no longer valid. // If the context flag UseCSharpNullComparisonBehavior was modified, then the plan is no longer valid. if ((explicitMergeOption.HasValue && explicitMergeOption.Value != plan.MergeOption) || this._recompileRequired() || this.ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior != this._useCSharpNullComparisonBehavior) { plan = null; } } // The plan may have been invalidated above, or this query may never have been prepared. if (plan == null) { // Metadata is required to generate the execution plan. this.ObjectContext.EnsureMetadata(); // Reset internal state this._recompileRequired = null; this.ResetParameters(); // Translate LINQ expression to a DbExpression ExpressionConverter converter = this.CreateExpressionConverter(); DbExpression queryExpression = converter.Convert(); // This delegate tells us when a part of the expression tree has changed requiring a recompile. this._recompileRequired = converter.RecompileRequired; // Determine the merge option, with the following precedence: // 1. A merge option was specified explicitly as the argument to Execute(MergeOption). // 2. The user has set the MergeOption property on the ObjectQuery instance. // 3. A merge option has been extracted from the 'root' query and propagated to the root of the expression tree. // 4. The global default merge option. MergeOption mergeOption = EnsureMergeOption(forMergeOption, this.UserSpecifiedMergeOption, converter.PropagatedMergeOption); this._useCSharpNullComparisonBehavior = this.ObjectContext.ContextOptions.UseCSharpNullComparisonBehavior; // If parameters were aggregated from referenced (non-LINQ) ObjectQuery instances then add them to the parameters collection _linqParameters = converter.GetParameters(); if (_linqParameters != null && _linqParameters.Count > 0) { ObjectParameterCollection currentParams = this.EnsureParameters(); currentParams.SetReadOnly(false); foreach (KeyValuePair <ObjectParameter, QueryParameterExpression> pair in _linqParameters) { // Note that it is safe to add the parameter directly only // because parameters are cloned before they are added to the // converter's parameter collection, or they came from this // instance's parameter collection in the first place. ObjectParameter convertedParam = pair.Key; currentParams.Add(convertedParam); } currentParams.SetReadOnly(true); } // Try retrieving the execution plan from the global query cache (if plan caching is enabled). System.Data.Common.QueryCache.QueryCacheManager cacheManager = null; System.Data.Common.QueryCache.LinqQueryCacheKey cacheKey = null; if (this.PlanCachingEnabled && !this._recompileRequired()) { // Create a new cache key that reflects the current state of the Parameters collection // and the Span object (if any), and uses the specified merge option. string expressionKey; if (ExpressionKeyGen.TryGenerateKey(queryExpression, out expressionKey)) { cacheKey = new System.Data.Common.QueryCache.LinqQueryCacheKey( expressionKey, (null == this.Parameters ? 0 : this.Parameters.Count), (null == this.Parameters ? null : this.Parameters.GetCacheKey()), (null == converter.PropagatedSpan ? null : converter.PropagatedSpan.GetCacheKey()), mergeOption, this._useCSharpNullComparisonBehavior, this.ElementType); cacheManager = this.ObjectContext.MetadataWorkspace.GetQueryCacheManager(); ObjectQueryExecutionPlan executionPlan = null; if (cacheManager.TryCacheLookup(cacheKey, out executionPlan)) { plan = executionPlan; } } } // If execution plan wasn't retrieved from the cache, build a new one and cache it. if (plan == null) { DbQueryCommandTree tree = DbQueryCommandTree.FromValidExpression(this.ObjectContext.MetadataWorkspace, DataSpace.CSpace, queryExpression); plan = ObjectQueryExecutionPlan.Prepare(this.ObjectContext, tree, this.ElementType, mergeOption, converter.PropagatedSpan, null, converter.AliasGenerator); // If caching is enabled then update the cache now. // Note: the logic is the same as in EntitySqlQueryState. if (cacheKey != null) { var newEntry = new QueryCacheEntry(cacheKey, plan); QueryCacheEntry foundEntry = null; if (cacheManager.TryLookupAndAdd(newEntry, out foundEntry)) { // If TryLookupAndAdd returns 'true' then the entry was already present in the cache when the attempt to add was made. // In this case the existing execution plan should be used. plan = (ObjectQueryExecutionPlan)foundEntry.GetTarget(); } } } // Remember the current plan in the local cache, so that we don't have to recalc the key and look into the global cache // if the same instance of query gets executed more than once. this._cachedPlan = plan; } // Evaluate parameter values for the query. if (_linqParameters != null) { foreach (KeyValuePair <ObjectParameter, QueryParameterExpression> pair in _linqParameters) { ObjectParameter parameter = pair.Key; QueryParameterExpression parameterExpression = pair.Value; if (null != parameterExpression) { parameter.Value = parameterExpression.EvaluateParameter(null); } } } return(plan); }
/// <summary> /// Constructor with an <see cref="ElementInit"/> and an <see cref="ExpressionConverter"/>. /// </summary> /// <param name="elementInit">The original, not serializable <see cref="ElementInit"/>.</param> /// <param name="expConverter">The <see cref="ExpressionConverter"/> to convert contained <see cref="Expression">Expressions</see>.</param> public SerializableElementInit(ElementInit elementInit, ExpressionConverter expConverter) { Arguments = elementInit.Arguments.MakeSerializableCollection <SerializableExpression>(expConverter); AddMethod = elementInit.AddMethod; }
/// <summary> /// Constructor with an <see cref="MemberInitExpression"/> and an <see cref="ExpressionConverter"/>. /// </summary> /// <param name="expression">The original, not serializable <see cref="Expression"/>.</param> /// <param name="expConverter">The <see cref="ExpressionConverter"/> to convert contained <see cref="Expression">Expressions</see>.</param> public SerializableMemberInitExpression(MemberInitExpression expression, ExpressionConverter expConverter) : base(expression, expConverter) { NewExpression = expression.NewExpression.MakeSerializable<SerializableNewExpression>(expConverter); Bindings = expConverter.ConvertToSerializableObjectCollection<SerializableMemberBinding>(expression.Bindings); }
/// <summary> /// Constructor with an <see cref="InvocationExpression"/> and an <see cref="ExpressionConverter"/>. /// </summary> /// <param name="expression">The original, not serializable <see cref="Expression"/>.</param> /// <param name="expConverter">The <see cref="ExpressionConverter"/> to convert contained <see cref="Expression">Expressions</see>.</param> public SerializableInvocationExpression(InvocationExpression expression, ExpressionConverter expConverter) : base(expression, expConverter) { Expression = expression.Expression.MakeSerializable(expConverter); Arguments = expression.Arguments.MakeSerializableCollection <SerializableExpression>(expConverter); }
public void Setup() { expressionConverter = new ExpressionConverter(); tokenizer = new Tokenizer(); parser = new PolynomialParser(tokenizer); }
public override ICode Convert(MethodCallExpression expression, ExpressionConverter converter) => new SingleTextCode(string.Empty);
/// <summary> /// Constructor with an <see cref="LambdaExpression"/> and an <see cref="ExpressionConverter"/>. /// </summary> /// <param name="expression">The original, not serializable <see cref="Expression"/>.</param> /// <param name="expConverter">The <see cref="ExpressionConverter"/> to convert contained <see cref="Expression">Expressions</see>.</param> public SerializableLambdaExpression(LambdaExpression expression, ExpressionConverter expConverter) : base(expression, expConverter) { Body = expression.Body.MakeSerializable(expConverter); Parameters = expression.Parameters.MakeSerializableCollection <SerializableParameterExpression>(expConverter); }
/// <summary> /// Convert expression to code. /// </summary> /// <param name="expression">Expression.</param> /// <param name="converter">Expression converter.</param> /// <returns>Parts.</returns> public abstract ICode Convert(MethodCallExpression expression, ExpressionConverter converter);
/// <summary> /// Convert expression to code. /// </summary> /// <param name="expression">Expression.</param> /// <param name="converter">Expression converter.</param> /// <returns>Parts.</returns> public override ICode Convert(MethodCallExpression expression, ExpressionConverter converter) { var args = _core.InitAndConvertArguments(expression, converter); var hArgs = new AroundCode(new HCode(args) { Separator = ", " }, "", ")"); return new HCode(Line(_core.NameCode, "(".ToCode()), hArgs) { AddIndentNewLine = true, Indent = Indent }; }
/// <summary> /// Constructor with an <see cref="NewArrayExpression"/> and an <see cref="ExpressionConverter"/>. /// </summary> /// <param name="expression">The original, not serializable <see cref="Expression"/>.</param> /// <param name="expConverter">The <see cref="ExpressionConverter"/> to convert contained <see cref="Expression">Expressions</see>.</param> public SerializableNewArrayExpression(NewArrayExpression expression, ExpressionConverter expConverter) : base(expression, expConverter) { Expressions = expression.Expressions.MakeSerializableCollection <SerializableExpression>(expConverter); }