Пример #1
0
        protected override Expression VisitConditional(ConditionalExpression expression)
        {
            if (invariantExpression || builder.SelectExpression != null)
            {
                return(base.VisitConditional(expression));
            }
            SPModelQueryExpressionScope currentScope = this.currentScope;
            SPModelQueryExpressionScope childScope = new SPModelQueryExpressionScope(this);
            CamlExpression condition, trueExpression, falseExpression;

            this.currentScope = childScope;

            VisitConditionalBranch(expression.Test);
            condition = childScope.Expression;

            childScope.Reset();
            Visit(expression.IfTrue);
            trueExpression = childScope.Expression;

            childScope.Reset();
            Visit(expression.IfFalse);
            falseExpression = childScope.Expression;

            currentScope.Expression = ((condition & trueExpression) | ((~condition) & falseExpression));
            this.currentScope       = currentScope;
            return(expression);
        }
        protected override Expression VisitUnary(UnaryExpression expression)
        {
            SPModelQueryExpressionScope currentScope = stack.Peek();
            SPModelQueryExpressionScope childScope   = new SPModelQueryExpressionScope(this);

            stack.Push(childScope);

            Visit(expression.Operand);
            switch (expression.NodeType)
            {
            case ExpressionType.Not:
                currentScope.Expression = ~childScope.Expression;
                break;

            case ExpressionType.Convert:
            case ExpressionType.ConvertChecked:
            case ExpressionType.Quote:
                childScope.CopyTo(currentScope);
                break;

            default:
                throw new NotSupportedException(String.Format("The unary operator '{0}' is not supported", expression.NodeType));
            }
            stack.Pop();
            return(expression);
        }
Пример #3
0
        protected override Expression VisitUnary(UnaryExpression expression)
        {
            if (invariantExpression || builder.SelectExpression != null)
            {
                return(base.VisitUnary(expression));
            }
            SPModelQueryExpressionScope currentScope = this.currentScope;
            SPModelQueryExpressionScope childScope   = new SPModelQueryExpressionScope(this);

            this.currentScope = childScope;

            Visit(expression.Operand);
            switch (expression.NodeType)
            {
            case ExpressionType.Not:
                currentScope.Expression = ~childScope.Expression;
                break;

            case ExpressionType.Convert:
            case ExpressionType.ConvertChecked:
            case ExpressionType.Quote:
                childScope.CopyTo(currentScope);
                break;

            default:
                throw new NotSupportedException(String.Format("Unary operator '{0}' is not supported", expression.NodeType));
            }
            this.currentScope = currentScope;
            return(expression);
        }
 public void CopyTo(SPModelQueryExpressionScope other)
 {
     CommonHelper.ConfirmNotNull(other, "other");
     other.Expression        = this.Expression;
     other.FieldAssociations = this.FieldAssociations;
     other.Field             = this.Field;
     other.Member            = this.Member;
     other.MemberType        = this.MemberType;
     other.ParameterName     = this.ParameterName;
 }
 public void CopyTo(SPModelQueryExpressionScope other)
 {
     CommonHelper.ConfirmNotNull(other, "other");
     other.Expression        = this.Expression;
     other.FieldAssociations = this.FieldAssociations;
     other.Field             = this.Field;
     other.Member            = this.Member;
     other.MemberType        = this.MemberType;
     other.IsValueDefined    = this.IsValueDefined;
     other.definedValue      = definedValue;
 }
Пример #6
0
        protected override Expression VisitMethodCall(MethodCallExpression expression)
        {
            if (invariantExpression)
            {
                return(base.VisitMethodCall(expression));
            }
            bool sameQueryable = expression.Method.DeclaringType == typeof(Queryable) && ContainsOrEquals(expression.Arguments[0], parameters[0]);

            if (builder.SelectExpression != null && !sameQueryable)
            {
                return(base.VisitMethodCall(expression));
            }

            SPModelQueryExpressionScope currentScope = this.currentScope;

            try {
                SPModelQueryExpressionScope childScope = new SPModelQueryExpressionScope(this);
                this.currentScope = childScope;

                if (sameQueryable)
                {
                    ValidateQueryableMethodCall(expression);

                    ParameterExpression currentLambdaParam = lambdaParam;
                    Visit(expression.Arguments[0]);
                    currentScope.Expression = childScope.Expression;
                    childScope.Reset();

                    currentScope.Expression += GetExpressionFromQueryableMethod(expression);
                    lambdaParam              = currentLambdaParam;
                    return(expression);
                }
                if (expression.Method.DeclaringType == typeof(Enumerable) || expression.Method.DeclaringType.IsOf(typeof(ICollection <>)))
                {
                    currentScope.Expression = GetExpressionFromEnumerableMethod(expression);
                    return(expression);
                }
                if (expression.Method.DeclaringType == typeof(string))
                {
                    currentScope.Expression = GetExpressionFromStringMethod(expression);
                    return(expression);
                }
                if (expression.Method.Name == "Equals" && expression.Arguments.Count == 1)
                {
                    Visit(expression.Object);
                    Visit(expression.Arguments[0]);
                    currentScope.Expression = childScope.GetExpression((SPModelQueryExpressionScope.ExpressionGenerator)Caml.Equals);
                    return(expression);
                }
                throw ThrowMethodNotSupported(expression.Method);
            } finally {
                this.currentScope = currentScope;
            }
        }
        protected override Expression VisitTypeIs(TypeBinaryExpression expression)
        {
            SPModelQueryExpressionScope currentScope = stack.Peek();

            try {
                SPModelDescriptor descriptor = SPModelDescriptor.Resolve(expression.TypeOperand);
                currentScope.Expression = descriptor.GetContentTypeExpression(manager.Descriptor);
            } catch (ArgumentException) {
                currentScope.Expression = Caml.False;
            }
            return(expression);
        }
        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);
        }
        protected override Expression VisitConditional(ConditionalExpression expression)
        {
            if (expression.Test.NodeType == ExpressionType.Constant)
            {
                if (true.Equals(((ConstantExpression)expression.Test).Value))
                {
                    Visit(expression.IfTrue);
                }
                else
                {
                    Visit(expression.IfFalse);
                }
            }
            else
            {
                SPModelQueryExpressionScope currentScope = stack.Peek();
                SPModelQueryExpressionScope childScope = new SPModelQueryExpressionScope(this);
                CamlExpression condition, trueExpression, falseExpression;
                stack.Push(childScope);

                Visit(expression.Test);
                condition = childScope.Expression;

                childScope.Reset();
                Visit(expression.IfTrue);
                trueExpression = childScope.Expression;

                childScope.Reset();
                Visit(expression.IfFalse);
                falseExpression = childScope.Expression;

                currentScope.Expression = ((condition & trueExpression) | ((~condition) & falseExpression));
                stack.Pop();
            }
            return(expression);
        }
        protected override Expression VisitBinary(BinaryExpression expression)
        {
            SPModelQueryExpressionScope currentScope  = stack.Peek();
            SPModelQueryExpressionScope childScope    = new SPModelQueryExpressionScope(this);
            SPModelQueryExpressionScope childScopeTwo = null;

            stack.Push(childScope);

            Visit(expression.Left);
            if (expression.NodeType == ExpressionType.AndAlso || expression.NodeType == ExpressionType.OrElse)
            {
                stack.Pop();
                childScopeTwo = new SPModelQueryExpressionScope(this);
                stack.Push(childScopeTwo);
            }
            Visit(expression.Right);

            switch (expression.NodeType)
            {
            case ExpressionType.AndAlso:
                currentScope.Expression = childScope.Expression & childScopeTwo.Expression;
                break;

            case ExpressionType.OrElse:
                currentScope.Expression = childScope.Expression | childScopeTwo.Expression;
                break;

            case ExpressionType.Equal:
                if (childScope.Value == null)
                {
                    currentScope.Expression = childScope.GetExpression(s => HandleNullExpression(s, false));
                }
                else
                {
                    currentScope.Expression = childScope.GetExpression((SPModelQueryExpressionScope.ExpressionGenerator)Caml.Equals);
                }
                break;

            case ExpressionType.NotEqual:
                if (childScope.Value == null)
                {
                    currentScope.Expression = childScope.GetExpression(s => HandleNullExpression(s, true));
                }
                else
                {
                    currentScope.Expression = childScope.GetExpression(Caml.NotEquals);
                }
                break;

            case ExpressionType.LessThan:
                currentScope.Expression = childScope.GetExpression(Caml.LessThan);
                break;

            case ExpressionType.LessThanOrEqual:
                currentScope.Expression = childScope.GetExpression(Caml.LessThanOrEqual);
                break;

            case ExpressionType.GreaterThan:
                currentScope.Expression = childScope.GetExpression(Caml.GreaterThan);
                break;

            case ExpressionType.GreaterThanOrEqual:
                currentScope.Expression = childScope.GetExpression(Caml.GreaterThanOrEqual);
                break;

            default:
                throw new NotSupportedException(String.Format("The binary operator '{0}' is not supported", expression.NodeType));
            }
            stack.Pop();
            return(expression);
        }
        protected override Expression VisitMethodCall(MethodCallExpression expression)
        {
            SPModelQueryExpressionScope currentScope = stack.Peek();
            SPModelQueryExpressionScope childScope   = new SPModelQueryExpressionScope(this);

            stack.Push(childScope);

            if (expression.Method.DeclaringType == typeof(Queryable))
            {
                Visit(expression.Arguments[0]);
                currentScope.Expression = childScope.Expression;
                childScope.Reset();

                switch (expression.Method.Name)
                {
                case "Where":
                    if (expression.Arguments.Count == 3)
                    {
                        throw new NotSupportedException(String.Format("The method '{0}' with element's index used in the logic is not supported", expression.Method.Name));
                    }
                    Visit(expression.Arguments[1]);
                    currentScope.Expression += childScope.Expression;
                    break;

                case "Union":
                    if (expression.Arguments.Count == 3)
                    {
                        throw new NotSupportedException(String.Format("The method '{0}' with element's index used in the logic is not supported", expression.Method.Name));
                    }
                    Visit(expression.Arguments[1]);
                    currentScope.Expression |= childScope.Expression;
                    break;

                case "Count":
                    result.ExecuteMode = Enum <SPModelQueryExecuteMode> .Parse(expression.Method.Name);

                    if (expression.Arguments.Count > 1)
                    {
                        Visit(expression.Arguments[1]);
                        currentScope.Expression += childScope.Expression;
                    }
                    break;

                case "All":
                case "Any":
                case "FirstOrDefault":
                case "First":
                case "SingleOrDefault":
                case "Single":
                case "ElementAtOrDefault":
                case "ElementAt":
                    result.ExecuteMode = Enum <SPModelQueryExecuteMode> .Parse(expression.Method.Name);

                    if (result.ExecuteMode == SPModelQueryExecuteMode.ElementAt || result.ExecuteMode == SPModelQueryExecuteMode.ElementAtOrDefault)
                    {
                        result.Limit += Math.Max(0, Convert.ToInt32(((ConstantExpression)expression.Arguments[1]).Value));
                    }
                    else if (result.ExecuteMode == SPModelQueryExecuteMode.Single || result.ExecuteMode == SPModelQueryExecuteMode.SingleOrDefault)
                    {
                        result.Limit = 2;
                    }
                    else
                    {
                        result.Limit = 1;
                    }
                    if (expression.Arguments.Count > 1)
                    {
                        Visit(expression.Arguments[1]);
                        currentScope.Expression += childScope.Expression;
                    }
                    break;

                case "Take":
                    result.Limit = Math.Max(0, Convert.ToInt32(((ConstantExpression)expression.Arguments[1]).Value));
                    break;

                case "Skip":
                    result.Offset = Math.Max(0, Convert.ToInt32(((ConstantExpression)expression.Arguments[1]).Value));
                    break;

                case "OrderBy":
                case "ThenBy":
                    if (expression.Arguments.Count == 3)
                    {
                        throw new NotSupportedException(String.Format("The method '{0}' with specified comparer is not supported", expression.Method.Name));
                    }
                    Visit(expression.Arguments[1]);
                    currentScope.Expression += childScope.GetExpression(s => Caml.OrderByAscending(s.FieldRef), true);
                    break;

                case "OrderByDescending":
                case "ThenByDescending":
                    if (expression.Arguments.Count == 3)
                    {
                        throw new NotSupportedException(String.Format("The method '{0}' with specified comparer is not supported", expression.Method.Name));
                    }
                    Visit(expression.Arguments[1]);
                    currentScope.Expression += childScope.GetExpression(s => Caml.OrderByDescending(s.FieldRef), true);
                    break;

                case "Select":
                    result.SelectExpression = (LambdaExpression)StripQuotes(expression.Arguments[1]);
                    break;

                case "OfType":
                    result.ModelType = expression.Method.GetGenericArguments()[0];
                    break;

                default:
                    throw new NotSupportedException(String.Format("The method '{0}' is not supported", expression.Method.Name));
                }
            }
            else if (expression.Method.DeclaringType == typeof(Enumerable))
            {
                switch (expression.Method.Name)
                {
                case "Contains":
                    if (expression.Arguments.Count == 3)
                    {
                        throw new NotSupportedException(String.Format("The method '{0}' with specified comparer is not supported", expression.Method.Name));
                    }
                    Visit(expression.Arguments[0]);
                    Visit(expression.Arguments[1]);
                    if (childScope.Value is IEnumerable)
                    {
                        if (((IEnumerable)childScope.Value).OfType <object>().Any())
                        {
                            currentScope.Expression = childScope.GetExpression(Caml.EqualsAny);
                        }
                        else
                        {
                            currentScope.Expression = CamlExpression.False;
                        }
                    }
                    else
                    {
                        currentScope.Expression = childScope.GetExpression(Caml.Includes);
                    }
                    break;

                default:
                    throw new NotSupportedException(String.Format("The method '{0}' is not supported", expression.Method.Name));
                }
            }
            else if (expression.Method.DeclaringType == typeof(String))
            {
                Visit(expression.Object);
                switch (expression.Method.Name)
                {
                case "StartsWith":
                    Visit(expression.Arguments[0]);
                    currentScope.Expression = childScope.GetExpression(s => Caml.BeginsWith(s.FieldRef, (childScope.Value ?? String.Empty).ToString()));
                    break;

                default:
                    throw new NotSupportedException(String.Format("The method '{0}' is not supported", expression.Method.Name));
                }
            }
            else if (expression.Method.DeclaringType.IsOf(typeof(ICollection <>)))
            {
                switch (expression.Method.Name)
                {
                case "Contains":
                    Visit(expression.Object);
                    Visit(expression.Arguments[0]);
                    if (childScope.Value is IEnumerable)
                    {
                        if (((IEnumerable)childScope.Value).OfType <object>().Any())
                        {
                            currentScope.Expression = childScope.GetExpression(Caml.EqualsAny);
                        }
                        else
                        {
                            currentScope.Expression = CamlExpression.False;
                        }
                    }
                    else
                    {
                        currentScope.Expression = childScope.GetExpression(Caml.Includes);
                    }
                    break;

                default:
                    throw new NotSupportedException(String.Format("The method '{0}' is not supported", expression.Method.Name));
                }
            }
            else if (expression.Method.Name == "Equals" && expression.Arguments.Count == 1)
            {
                Visit(expression.Object);
                Visit(expression.Arguments[0]);
                currentScope.Expression = childScope.GetExpression((SPModelQueryExpressionScope.ExpressionGenerator)Caml.Equals);
            }
            else
            {
                throw new NotSupportedException(String.Format("The method '{0}' is not supported", expression.Method.Name));
            }
            stack.Pop();
            return(expression);
        }
        protected override Expression VisitMemberAccess(MemberExpression expression)
        {
            SPModelQueryExpressionScope currentScope = stack.Peek();

            switch (expression.Expression.NodeType)
            {
            case ExpressionType.Parameter:
            case ExpressionType.MemberAccess:
            case ExpressionType.Convert:
            case ExpressionType.Call:
                if (expression.Member.DeclaringType == typeof(ISPModelMetaData))
                {
                    switch (expression.Member.Name)
                    {
                    case "ID":
                        currentScope.Field = SPModelQueryFieldInfo.ID;
                        break;

                    case "UniqueId":
                        currentScope.Field = SPModelQueryFieldInfo.UniqueId;
                        break;

                    case "FileRef":
                        currentScope.Field = SPModelQueryFieldInfo.FileRef;
                        break;

                    case "FileLeafRef":
                        currentScope.Field = SPModelQueryFieldInfo.FileLeafRef;
                        break;

                    case "LastModified":
                        currentScope.Field = SPModelQueryFieldInfo.LastModified;
                        break;

                    case "CheckOutUserID":
                        currentScope.Field = SPModelQueryFieldInfo.CheckOutUserID;
                        break;

                    default:
                        throw new NotSupportedException(String.Format("The member '{0}' is not supported", expression.Member.Name));
                    }
                }
                else if (expression.Member.DeclaringType == typeof(TaxonomyItem) || expression.Member.DeclaringType == typeof(SPPrincipal))
                {
                    switch (expression.Member.Name)
                    {
                    case "Id":
                    case "ID":
                        Visit(expression.Expression);
                        break;

                    default:
                        throw new NotSupportedException(String.Format("The member '{0}' is not supported", expression.Member.Name));
                    }
                }
                else
                {
                    currentScope.MemberType        = expression.Type;
                    currentScope.Member            = expression.Member;
                    currentScope.FieldAssociations = SPModelFieldAssociationCollection.GetByMember(expression.Member);
                }
                break;

            default:
                throw new NotSupportedException(String.Format("The member '{0}' is not supported", expression.Member.Name));
            }
            return(expression);
        }
Пример #13
0
 private SPModelQueryExpressionVisitor(ISPModelManagerInternal manager, ReadOnlyCollection <ParameterExpression> parameters)
 {
     this.manager      = manager;
     this.parameters   = parameters;
     this.currentScope = new SPModelQueryExpressionScope(this);
 }
Пример #14
0
        protected override Expression VisitBinary(BinaryExpression expression)
        {
            if (invariantExpression || builder.SelectExpression != null)
            {
                return(base.VisitBinary(expression));
            }
            SPModelQueryExpressionScope currentScope  = this.currentScope;
            SPModelQueryExpressionScope childScope    = new SPModelQueryExpressionScope(this);
            SPModelQueryExpressionScope childScopeTwo = null;

            this.currentScope = childScope;

            if (expression.NodeType == ExpressionType.AndAlso || expression.NodeType == ExpressionType.OrElse)
            {
                childScopeTwo = new SPModelQueryExpressionScope(this);
                VisitConditionalBranch(expression.Left);
                this.currentScope = childScopeTwo;
                VisitConditionalBranch(expression.Right);
            }
            else
            {
                Visit(expression.Left);
                Visit(expression.Right);
            }
            switch (expression.NodeType)
            {
            case ExpressionType.AndAlso:
                currentScope.Expression = childScope.Expression & childScopeTwo.Expression;
                break;

            case ExpressionType.OrElse:
                currentScope.Expression = childScope.Expression | childScopeTwo.Expression;
                break;

            case ExpressionType.Equal:
                currentScope.Expression = childScope.GetExpression(s => HandleEqualityComparison(s, CamlBinaryOperator.Eq));
                break;

            case ExpressionType.NotEqual:
                currentScope.Expression = childScope.GetExpression(s => HandleEqualityComparison(s, CamlBinaryOperator.Neq));
                break;

            case ExpressionType.LessThan:
                currentScope.Expression = childScope.GetExpression(Caml.LessThan);
                break;

            case ExpressionType.LessThanOrEqual:
                currentScope.Expression = childScope.GetExpression(Caml.LessThanOrEqual);
                break;

            case ExpressionType.GreaterThan:
                currentScope.Expression = childScope.GetExpression(Caml.GreaterThan);
                break;

            case ExpressionType.GreaterThanOrEqual:
                currentScope.Expression = childScope.GetExpression(Caml.GreaterThanOrEqual);
                break;

            default:
                throw new NotSupportedException(String.Format("Binary operator '{0}' is not supported", expression.NodeType));
            }
            this.currentScope = currentScope;
            return(expression);
        }