예제 #1
0
        public override string GetQueryText(Expression expression)
        {
            var partial = PartialEvaluator.Eval(expression);

            return(Serialize(new WebLinqVisitor(SourceExpression)
                             .Visit(partial)));
        }
예제 #2
0
        private string BinarExpressionProvider(Expression left, Expression right, ExpressionType type)
        {
            string text = "(";

            left  = PartialEvaluator.Eval(left);
            text += this.ExpressionRouter(left);
            text += this.ExpressionTypeCast(type);
            right = PartialEvaluator.Eval(right);
            string text2 = this.ExpressionRouter(right);

            if (text2 == "null")
            {
                if (text.EndsWith(" ="))
                {
                    text = text.Substring(0, text.Length - 2) + " is null";
                }
                else if (text.EndsWith("<>"))
                {
                    text = text.Substring(0, text.Length - 2) + " is not null";
                }
            }
            else
            {
                text += text2;
            }
            return(text + ")");
        }
예제 #3
0
        /// <summary>
        /// 通过一个 <see cref="MemberInitExpression"/> 表达式将属性值绑定到实体对象中。
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="creator"></param>
        /// <returns></returns>
        public static IEntity InitByExpression(this IEntity entity, LambdaExpression creator)
        {
            if (creator.Body is NewExpression)
            {
                throw new InvalidOperationException(SR.GetString(SRKind.InvalidExpressionInit));
            }

            if (creator.Body is MemberInitExpression initExp)
            {
                if (initExp.NewExpression.Arguments.Count > 0)
                {
                    throw new InvalidOperationException(SR.GetString(SRKind.InvalidExpressionInit));
                }

                foreach (var bind in initExp.Bindings)
                {
                    if (bind as MemberAssignment == null)
                    {
                        continue;
                    }

                    var exp = PartialEvaluator.Eval((bind as MemberAssignment).Expression);
                    if (exp is ConstantExpression constExp)
                    {
                        entity.SetValue((bind as MemberAssignment).Member.Name, PropertyValue.NewValue(constExp.Value, (bind as MemberAssignment).Member.GetMemberType()));
                    }
                }
            }

            return(entity);
        }
예제 #4
0
            protected override MemberBinding VisitBinding(MemberBinding binding)
            {
                var assign = binding as MemberAssignment;

                if (assign == null)
                {
                    return(binding);
                }

                var propertyName = assign.Member.Name;
                var property     = PropertyUnity.GetProperty(typeof(TEntity), propertyName);

                if (property != null)
                {
                    if (condition.Length > 0)
                    {
                        condition.Append(" AND ");
                    }

                    var constExp = PartialEvaluator.Eval(assign.Expression) as ConstantExpression;
                    if (constExp.Type.IsStringOrDateTime())
                    {
                        condition.AppendFormat("{0} = '{1}'", property.Info.FieldName, constExp.Value);
                    }
                    else
                    {
                        condition.AppendFormat("{0} = {1}", property.Info.FieldName, constExp.Value);
                    }
                }

                return(binding);
            }
예제 #5
0
        /// <summary>
        /// Parses a <c>where</c> expression.
        /// </summary>
        /// <param name="expression">Expression to parse.</param>
        /// <param name="previousParameters">Previous parameters, whose values should be included in the result.</param>
        public static QueryParameters <TSource, TResult> ParseWhere <TSource, TResult, TWhere>(
            Expression <Func <TWhere, bool> > expression, QueryParameters <TSource, TResult> previousParameters)
        {
            var body = EnumFixer.Fix(PartialEvaluator.Eval(expression.Body));

            return(ParseWhereSubexpression(body, previousParameters));
        }
예제 #6
0
        protected override Expression VisitSelect(SelectExpression select)
        {
            // select * from table order by x skip s take t
            // =>
            // select * from (select top s * from (select top s + t from table order by x) order by -x) order by x

            select = (SelectExpression)base.VisitSelect(select);

            if (select.Skip != null && select.Take != null && select.OrderBy.Count > 0)
            {
                Expression skip         = select.Skip;
                Expression take         = select.Take;
                Expression skipPlusTake = PartialEvaluator.Eval(Expression.Add(skip, take));

                select = select.SetTake(skipPlusTake).SetSkip(null);
                select = select.AddRedundantSelect(language, new TableAlias());
                select = select.SetTake(take);

                // propogate order-bys to new layer
                select = (SelectExpression)OrderByRewriter.Rewrite(language, select);
                IEnumerable <OrderExpression> inverted = select.OrderBy.Select(ob => new OrderExpression(ob.OrderType == OrderType.Ascending ? OrderType.Descending : OrderType.Ascending, ob.Expression));
                select = select.SetOrderBy(inverted);

                select = select.AddRedundantSelect(language, new TableAlias());
                select = select.SetTake(Expression.Constant(0)); // temporary
                select = (SelectExpression)OrderByRewriter.Rewrite(language, select);
                IEnumerable <OrderExpression> reverted = select.OrderBy.Select(ob => new OrderExpression(ob.OrderType == OrderType.Ascending ? OrderType.Descending : OrderType.Ascending, ob.Expression));
                select = select.SetOrderBy(reverted);
                select = select.SetTake(null);
            }

            return(select);
        }
예제 #7
0
        protected override Expression Visit(Expression exp)
        {
            exp = PartialEvaluator.Eval(exp, CanBeEvaluatedLocally);
            Expression result = base.Visit(exp);

            if (result != null)
            {
                // bindings that expect projections should have called VisitSequence, the rest will probably get annoyed if
                // the projection does not have the expected type.
                Type expectedType = exp.Type;
                var  projection   = result as ProjectionExpression;
                if (projection != null && projection.Aggregator == null &&
                    !expectedType.IsAssignableFrom(projection.Type))
                {
                    LambdaExpression aggregator =
                        Aggregator.GetAggregator(expectedType, projection.Type);

                    if (aggregator != null)
                    {
                        return(new ProjectionExpression(projection.Select,
                                                        projection.Projector, aggregator));
                    }
                }
            }

            return(result);
        }
예제 #8
0
        internal Expression ProcessWhereWithResourceRoot(Expression rootExpression, MethodCallExpression whereExpression, bool insideNavPropertyWithGetReferenceCmdlet = false)
        {
            ICommand         command;
            LambdaExpression operand = (LambdaExpression)((UnaryExpression)whereExpression.Arguments[1]).Operand;

            operand = (LambdaExpression)PartialEvaluator.Eval(operand);
            ResourceType   initialResourceType = this.GetInitialResourceType();
            EntityMetadata entityMetadatum     = this.schema.EntityMetadataDictionary[initialResourceType.FullName];

            if (!insideNavPropertyWithGetReferenceCmdlet)
            {
                command = DataServiceController.Current.GetCommand(CommandType.Read, this.userContext, initialResourceType, entityMetadatum, this.membershipId);
            }
            else
            {
                command = new ReferenceInstanceBuilderCommand(initialResourceType, entityMetadatum);
            }
            DataServiceQueryProvider.ResultSet resultSet = null;
            using (command)
            {
                operand = this.InvokeFilteredGet(command, initialResourceType, operand, out resultSet);
            }
            DSMethodTranslatingVisitor dSMethodTranslatingVisitor = new DSMethodTranslatingVisitor(this.resultSets);

            operand = dSMethodTranslatingVisitor.VisitAndConvert <LambdaExpression>(operand, "ProcessWhereWithResourceRoot");
            Func <DSResource, bool> func                   = (Func <DSResource, bool>)operand.Compile();
            IQueryable <DSResource> dSResources            = resultSet.Where <DSResource>((DSResource item) => func(item)).AsQueryable <DSResource>();
            ExpressionNodeReplacer  expressionNodeReplacer = new ExpressionNodeReplacer(whereExpression, Expression.Constant(dSResources));
            Expression expression = expressionNodeReplacer.Visit(rootExpression);

            return(expression);
        }
예제 #9
0
 internal bool TryAddingAllExpressions(Expression rootExpression, Expression baseExpression, ICommand command, DataServiceQueryProvider.ResultSet resultSet, out Expression nodeToReplace)
 {
     if (!ExpressionHelper.IsResourceRoot(baseExpression, this.initialQueryable))
     {
         MethodCallExpression methodCallExpression = baseExpression as MethodCallExpression;
         bool flag = this.TryAddingAllExpressions(rootExpression, methodCallExpression.Arguments[0], command, resultSet, out nodeToReplace);
         if (!flag)
         {
             return(false);
         }
         else
         {
             LambdaExpression operand = (LambdaExpression)((UnaryExpression)methodCallExpression.Arguments[1]).Operand;
             operand = (LambdaExpression)PartialEvaluator.Eval(operand);
             CommandArgumentVisitor commandArgumentVisitor = new CommandArgumentVisitor(command);
             operand = commandArgumentVisitor.VisitAndConvert <LambdaExpression>(operand, "TryAddingAllExpressions");
             if (!ExpressionHelper.IsConstantTrue(operand.Body))
             {
                 return(false);
             }
             else
             {
                 nodeToReplace = methodCallExpression;
                 return(true);
             }
         }
     }
     else
     {
         nodeToReplace = baseExpression;
         return(true);
     }
 }
예제 #10
0
 protected override Expression VisitProjection(DbProjectionExpression proj)
 {
     if (proj.Select.Skip != null)
     {
         Expression newTake = (proj.Select.Take != null) ? Expression.Add(proj.Select.Skip, proj.Select.Take) : null;
         if (newTake != null)
         {
             newTake = PartialEvaluator.Eval(newTake);
         }
         var newSelect   = proj.Select.SetSkip(null).SetTake(newTake);
         var elementType = proj.Type.GetSequenceElementType();
         var agg         = proj.Aggregator;
         var p           = agg != null ? agg.Parameters[0] : Expression.Parameter(elementType, "p");
         var skip        = Expression.Call(typeof(Enumerable), "Skip", new Type[] { elementType }, p, proj.Select.Skip);
         if (agg != null)
         {
             agg = (LambdaExpression)DbExpressionReplacer.Replace(agg, p, skip);
         }
         else
         {
             agg = Expression.Lambda(skip, p);
         }
         return(new DbProjectionExpression(newSelect, proj.Projector, agg));
     }
     return(proj);
 }
예제 #11
0
        Expression IQueryPolicy.ApplyPolicy(Expression expression, MemberInfo member)
        {
            List <LambdaExpression> ops;

            if (operations.TryGetValue(member, out ops))
            {
                var syntax = Database.Provider.GetService <ISyntaxProvider>();
                var result = expression;
                foreach (var fnOp in ops)
                {
                    var pop = PartialEvaluator.Eval(fnOp);
                    result = QueryBinder.Bind(Expression.Invoke(pop, result), syntax);
                }

                var projection = (ProjectionExpression)result;
                if (projection.Type != expression.Type)
                {
                    var fnAgg = QueryUtility.GetAggregator(expression.Type, projection.Type);
                    projection = new ProjectionExpression(projection.Select, projection.Projector, fnAgg);
                }

                return(projection);
            }

            return(expression);
        }
예제 #12
0
        /// <summary>
        /// 对表达式进行解析,并返回限制数组。
        /// </summary>
        /// <param name="indexes">数据提供者类别。</param>
        /// <param name="metadataType">架构元数组类型。</param>
        /// <param name="expression">查询表达式。</param>
        /// <returns></returns>
        public static string[] GetRestriction(Dictionary <string, int> indexes, Type metadataType, Expression expression)
        {
            var translator = new SchemaQueryTranslator(indexes, metadataType);

            expression = PartialEvaluator.Eval(expression);
            return(translator.GetRestrictionValues(expression));
        }
예제 #13
0
        /// <summary>
        /// Visits the method call.
        /// </summary>
        /// <param name="exp">The method call expression.</param>
        /// <returns>
        /// Reuced expression
        /// </returns>
        protected override Expression VisitMethodCall(MethodCallExpression exp)
        {
            Expression evaluated = PartialEvaluator.Eval(exp, CanBeEvaluatedLocally);

            if (evaluated is ConstantExpression constantExp)
            {
                AddParameterWithValue(GetConstantExpressionValue(constantExp));
                return(evaluated);
            }

            if (evaluated is MethodCallExpression methodCallExp)
            {
                if (methodCallExp.Method.DeclaringType == typeof(Queryable))
                {
                    VisitLinqMethods(methodCallExp);

                    return(Visit(methodCallExp.Arguments[0]));
                }
                if (methodCallExp.Method.DeclaringType == typeof(string))
                {
                    return(VisitStringMethods(methodCallExp));
                }
            }
            return(ThrowNotSupportedException(exp));
        }
예제 #14
0
        public override object Execute(Expression expression)
        {
            var visitor = new SalesforceVisitor(SelectType);
            var cmd     = visitor.Translate(PartialEvaluator.Eval(expression));

            switch (visitor.QueryType)
            {
            case QueryTypeEnum.FirstOrDefault:
                return(GetEnumerable(cmd).FirstOrDefault());

            case QueryTypeEnum.First:
                return(GetEnumerable(cmd).First());

            case QueryTypeEnum.Single:
                return(GetEnumerable(cmd).Single());

            case QueryTypeEnum.SingleOrDefault:
                return(GetEnumerable(cmd).SingleOrDefault());

            case QueryTypeEnum.Count:
                return(GetCount(cmd));

            case QueryTypeEnum.Any:
                return(GetCount(cmd) > 0);

            default:
                return(GetEnumerable(cmd));
            }
        }
예제 #15
0
        /// <summary>
        /// 通过一个 <see cref="MemberInitExpression"/> 表达式将属性值绑定到实体对象中。
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="factory"></param>
        /// <returns></returns>
        public static IEntity InitByExpression(this IEntity entity, LambdaExpression factory)
        {
            var initExp = factory.Body as MemberInitExpression;

            if (initExp != null)
            {
                foreach (var b in initExp.Bindings)
                {
                    var assign = b as MemberAssignment;
                    if (assign == null)
                    {
                        continue;
                    }

                    var exp      = PartialEvaluator.Eval(assign.Expression);
                    var constExp = exp as ConstantExpression;
                    if (constExp != null)
                    {
                        entity.SetValue(assign.Member.Name, PropertyValue.New(constExp.Value, assign.Member.GetMemberType()));
                    }
                }
            }

            return(entity);
        }
예제 #16
0
        /// <summary>
        /// Visits the select.
        /// </summary>
        /// <param name="select">The select.</param>
        /// <returns></returns>
        protected override Expression VisitSelect(SelectExpression select)
        {
            select = (SelectExpression)base.VisitSelect(select);

            if (select.Skip != null && select.Take != null && select.OrderBy.Count > 0)
            {
                var skip         = select.Skip;
                var take         = select.Take;
                var skipPlusTake = PartialEvaluator.Eval(Expression.Add(skip, take));

                select = select.SetTake(skipPlusTake).SetSkip(null);
                select = select.AddRedundantSelect(this.language, new TableAlias());
                select = select.SetTake(take);

                // propagate order-bys to new layer
                select = (SelectExpression)OrderByRewriter.Rewrite(this.language, select);
                var inverted = select.OrderBy.Select(ob => new OrderExpression(ob.OrderType == OrderType.Ascending ? OrderType.Descending : OrderType.Ascending, ob.Expression));
                select = select.SetOrderBy(inverted);

                select = select.AddRedundantSelect(this.language, new TableAlias());
                select = select.SetTake(Expression.Constant(0)); // temporary
                select = (SelectExpression)OrderByRewriter.Rewrite(this.language, select);
                var reverted = select.OrderBy.Select(ob => new OrderExpression(ob.OrderType == OrderType.Ascending ? OrderType.Descending : OrderType.Ascending, ob.Expression));
                select = select.SetOrderBy(reverted);
                select = select.SetTake(null);
            }

            return(select);
        }
예제 #17
0
 internal void Compile(params object[] args)
 {
     if (this.fnQuery == null)
     {
         // first identify the query provider being used
         Expression         body = this.query.Body;
         ConstantExpression root = RootQueryableFinder.Find(body) as ConstantExpression;
         if (root == null && args != null && args.Length > 0)
         {
             Expression replaced = ExpressionReplacer.ReplaceAll(
                 body,
                 this.query.Parameters.ToArray(),
                 args.Select((a, i) => Expression.Constant(a, this.query.Parameters[i].Type)).ToArray()
                 );
             body = PartialEvaluator.Eval(replaced);
             root = RootQueryableFinder.Find(body) as ConstantExpression;
         }
         if (root == null)
         {
             throw new InvalidOperationException("Could not find query provider");
         }
         // ask the query provider to compile the query by 'executing' the lambda expression
         IQueryProvider provider = ((IQueryable)root.Value).Provider;
         Delegate       result   = (Delegate)provider.Execute(this.query);
         System.Threading.Interlocked.CompareExchange(ref this.fnQuery, result, null);
     }
 }
예제 #18
0
        /// <summary>
        /// Optimizes the query without executing it.
        /// Used for unit tests.
        /// </summary>
        public static Expression OptimizeQuery(Expression inputExpression)
        {
            Expression partiallyEvaluatedExpression = PartialEvaluator.Eval(inputExpression, CanBeEvaluatedStatically);
            Expression expression = new ConvertToQueryAstVisitor(new QueryExecutionOptions()).Visit(partiallyEvaluatedExpression);

            return(new OptimizeQueryExpressionVisitor().Visit(expression));
        }
예제 #19
0
            public override Expression ApplyPolicy(Expression expression, MemberInfo member)
            {
                List <LambdaExpression> ops;

                if (this.policy.operations.TryGetValue(member, out ops))
                {
                    var result = expression;

                    foreach (var fnOp in ops)
                    {
                        var pop = PartialEvaluator.Eval(fnOp, this.Translator.Mapper.Mapping.CanBeEvaluatedLocally);
                        result = this.Translator.Mapper.ApplyMapping(Expression.Invoke(pop, result));
                    }

                    var projection = (ProjectionExpression)result;
                    if (projection.Type != expression.Type)
                    {
                        var fnAgg = Aggregator.GetAggregator(expression.Type, projection.Type);
                        projection = new ProjectionExpression(projection.Select, projection.Projector, fnAgg);
                    }

                    return(projection);
                }

                return(expression);
            }
예제 #20
0
        internal Expression ProcessSelectExpansion(Expression rootExpression, MethodCallExpression selectExpression)
        {
            LambdaExpression operand = (LambdaExpression)((UnaryExpression)selectExpression.Arguments[1]).Operand;

            operand = (LambdaExpression)PartialEvaluator.Eval(operand);
            List <ResourceProperty> refPropertiesUsed = GetRefPropertiesUsed(operand);
            IQueryable <DSResource> source            = this.EvaluateByLinqToObjects(selectExpression.Arguments[0]) as IQueryable <DSResource>;

            foreach (ResourceProperty property in refPropertiesUsed)
            {
                ResourceType resourceType = property.ResourceType;
                DataServiceQueryProvider.ResultSet associatedInstances = this.GetAssociatedInstances(source, property);
                DataServiceQueryProvider.ResultSet set2 = null;
                if (this.resultSets.TryGetValue(resourceType.Name, out set2))
                {
                    set2.Concat <DSResource>(associatedInstances);
                }
                else
                {
                    this.resultSets[resourceType.Name] = associatedInstances;
                }
            }
            MethodCallExpression expression = new DSMethodTranslatingVisitor(this.resultSets).VisitAndConvert <MethodCallExpression>(selectExpression, "ProcessSelectExpansion");
            object obj2     = source.Provider.CreateQuery(expression);
            var    ___Site4 = CallSite <Func <CallSite, Type, MethodCallExpression, object, ExpressionNodeReplacer> > .Create(Microsoft.CSharp.RuntimeBinder.Binder.InvokeConstructor(CSharpBinderFlags.None, typeof(DSLinqQueryProvider), new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.IsStaticType | CSharpArgumentInfoFlags.UseCompileTimeType, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null), CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) }));

            return(___Site4.Target(___Site4, typeof(ExpressionNodeReplacer), selectExpression, Expression.Constant((dynamic)obj2)).Visit(rootExpression));
        }
예제 #21
0
            public static Expression Replace(Expression where, Expression expression, IEnumerable <ColumnDeclaration> columns)
            {
                var visitor = new PolicyConditionReplacer {
                    _where = where, _columns = columns
                };

                visitor.Visit(PartialEvaluator.Eval(expression));
                return(visitor._where);
            }
예제 #22
0
 public override string ToString()
 {
     using (var sw = new StringWriter())
         using (JsonWriter = new JsonWriter(sw))
         {
             expression = PartialEvaluator.Eval(expression);
             WriteSegment(expression);
             return(sw.ToString());
         }
 }
예제 #23
0
        public virtual Expression Translate(Expression expression)
        {
            QueryMapping mapping = this.mapper.Mapping;

            expression = PartialEvaluator.Eval(expression, new Func <Expression, bool>(mapping.CanBeEvaluatedLocally));
            expression = this.mapper.Translate(expression);
            expression = this.police.Translate(expression);
            expression = this.linguist.Translate(expression);
            return(expression);
        }
예제 #24
0
        public void EvalTest2()
        {
            var local = "test";
            Expression <Func <string, bool> > expression = a => a.StartsWith(local);
            Expression <Func <string, bool> > expected   = a => a.StartsWith("test");
            Expression actual;

            actual = PartialEvaluator.Eval(expression);
            Assert.AreEqual(expected.ToString(), actual.ToString());
        }
예제 #25
0
        public void EvalTest1()
        {
            var local = "test";
            Expression <Func <string, string> > expression = a => a + local;
            Expression <Func <string, string> > expected   = a => a + "test";
            Expression actual;

            actual = PartialEvaluator.Eval(expression);
            Assert.AreEqual(expected.ToString(), actual.ToString());
        }
예제 #26
0
        public void EvalTest3()
        {
            var local = 1;
            Expression <Func <User, bool> > expression = a => a.ID == 0 + local;
            Expression <Func <User, bool> > expected   = a => a.ID == 1;
            Expression actual;

            actual = PartialEvaluator.Eval(expression);
            Assert.AreEqual(expected.ToString(), actual.ToString());
        }
예제 #27
0
        public void Build(Expression expression, DbCommand dbCommand)
        {
            this._DbCommand = dbCommand;
            PartialEvaluator evaluator           = new PartialEvaluator();
            Expression       evaluatedExpression = evaluator.Eval(expression);

            this.m_conditionParts = new Stack <string>();
            this.Visit(evaluatedExpression);
            this.Condition = this.m_conditionParts.Count > 0 ? this.m_conditionParts.Pop() : null;
            this._DbCommand.CommandText = this.Condition;
        }
예제 #28
0
        /// <summary>
        /// 通过表达式计算出对应的缓存键。
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        private static string GetKey(Expression expression)
        {
            var evalExp  = PartialEvaluator.Eval(expression, TranslateProviderBase.EvaluatedLocallyFunc);
            var cacheKey = ExpressionWriter.WriteToString(evalExp);

            //使用md5进行hash编码
            var md5 = new MD5CryptoServiceProvider();

            byte[] data = md5.ComputeHash(Encoding.Unicode.GetBytes(cacheKey));
            return("$." + Convert.ToBase64String(data, Base64FormattingOptions.None));
        }
        public SPModelQueryExpressionTranslateResult Translate(Expression expression)
        {
            CommonHelper.ConfirmNotNull(expression, "expression");
            SPModelQueryExpressionScope currentScope = new SPModelQueryExpressionScope(this);

            stack.Push(currentScope);

            Expression evaledExpression = PartialEvaluator.Eval(expression, CanBeEvaluatedLocally);

            Visit(evaledExpression);
            result.Expression = currentScope.Expression;
            return(result);
        }
예제 #30
0
 public void Build(Expression expression)
 {
     this.Condition = "";
     if (expression != null)
     {
         PartialEvaluator partialEvaluator = new PartialEvaluator();
         Expression       expression2      = partialEvaluator.Eval(expression);
         this.m_arguments      = new List <object>();
         this.m_conditionParts = new Stack <object>();
         this.Visit(expression2);
         this.Arguments = this.m_arguments.ToArray();
         this.Condition = ((this.m_conditionParts.Count > 0) ? (this.m_conditionParts.Pop() as string) : "");
     }
 }