コード例 #1
0
        // ==================================================================================================================================================
        private ContentSet <Q> Clone <Q>(Expression expression)
        {
            if (typeof(Content) != typeof(Q))
            {
                this.TypeFilter = typeof(Q);
            }
            if (typeof(Q) == typeof(Content) || typeof(Node).IsAssignableFrom(typeof(Q)))
            {
                return new ContentSet <Q>(expression, this.ChildrenDefinition.Clone(), this.ContextPath)
                       {
                           CountOnlyEnabled   = this.CountOnlyEnabled,
                           HeadersOnlyEnabled = this.HeadersOnlyEnabled,
                           TypeFilter         = this.TypeFilter
                       }
            }
            ;
            if (expression is MethodCallExpression callExpr)
            {
                var lastMethodName = callExpr.Method.Name;

                throw SnExpression.CallingAsEnunerableExpectedError(lastMethodName);
            }
            throw SnExpression.CallingAsEnunerableExpectedError(expression);
        }
コード例 #2
0
ファイル: SnLinqVisitor.cs プロジェクト: y1027/sensenet
        protected override Expression VisitMethodCall(MethodCallExpression node)
        {
            Trace(MethodBase.GetCurrentMethod(), node);
            Expression visited = null;

            try
            {
                visited = base.VisitMethodCall(node);
            }
            catch (SnNotSupportedException e)
            {
                throw SnExpression.CallingAsEnunerableExpectedError(node.Method.Name, e);
            }

            if (!(visited is MethodCallExpression methodCallExpr))
            {
                throw new NotSupportedException("#VisitMethodCall if visited is not null");
            }

            var methodName = methodCallExpr.Method.Name;

            switch (methodName)
            {
            case "OfType":
            // Do nothing. Type of expression has been changed so a TypeIs predicate will be created.
            case "Where":
                // do nothing
                break;

            case "Take":
                var topExpr = GetArgumentAsConstant(methodCallExpr, 1);
                this.Top = (int)topExpr.Value;
                break;

            case "Skip":
                var skipExpr = GetArgumentAsConstant(methodCallExpr, 1);
                this.Skip = (int)skipExpr.Value;
                break;

            case "LongCount":
            case "Count":
                if (methodCallExpr.Arguments.Count == 2)
                {
                    if (_predicates.Count > 1)     // There is Where in the main expression
                    {
                        CombineTwoPredicatesOnStack();
                    }
                }
                this.CountOnly = true;
                break;

            case "ThenBy":
            case "OrderBy":
                Sort.Add(CreateSortInfoFromExpr(node, false));
                break;

            case "ThenByDescending":
            case "OrderByDescending":
                Sort.Add(CreateSortInfoFromExpr(node, true));
                break;

            case "StartsWith":
                var startsWithExpr = GetArgumentAsConstant(methodCallExpr, 0);
                var startsWithArg  = (string)startsWithExpr.Value;
                BuildWildcardPredicate(GetPropertyName(methodCallExpr.Object), WildcardPosition.AtEnd, startsWithArg);
                break;

            case "EndsWith":
                var endsWithExpr = GetArgumentAsConstant(methodCallExpr, 0);
                var endsWithArg  = (string)endsWithExpr.Value;
                BuildWildcardPredicate(GetPropertyName(methodCallExpr.Object), WildcardPosition.AtStart, endsWithArg);
                break;

            case "Contains":
                var arg0 = methodCallExpr.Arguments[0];
                if (arg0 is ConstantExpression constantExpr)
                {
                    if (constantExpr.Type != typeof(string))
                    {
                        throw new NotSupportedException(
                                  $"Calling Contains on an instance of type {constantExpr.Type} is not supported. Allowed types: string, IEnumerable<Node>.");
                    }
                    var containsArg = (string)constantExpr.Value;
                    BuildWildcardPredicate(GetPropertyName(methodCallExpr.Object), WildcardPosition.AtStartAndEnd, containsArg);
                    break;
                }
                if (arg0 is MemberExpression memberExpr)
                {
                    if (memberExpr.Type != typeof(IEnumerable <Node>))
                    {
                        throw NotSupportedException(node, "#2");
                    }
                    if (!(methodCallExpr.Arguments[1] is ConstantExpression rightConstant))
                    {
                        throw NotSupportedException(node, "#1");
                    }
                    var nodeValue = (Node)rightConstant.Value;
                    BuildTextPredicate(memberExpr.Member.Name, nodeValue);
                    break;
                }
                throw NotSupportedException(node, "#3");

            case "FirstOrDefault":
            case "First":
                ElementSelection  = "first";
                this.Top          = 1;
                this.ThrowIfEmpty = methodName == "First";
                if (methodCallExpr.Arguments.Count == 2)
                {
                    if (_predicates.Count > 1)
                    {
                        CombineTwoPredicatesOnStack();
                    }
                }
                break;

            case "SingleOrDefault":
            case "Single":
                ElementSelection  = "single";
                this.ThrowIfEmpty = methodName == "Single";
                if (methodCallExpr.Arguments.Count == 2)
                {
                    if (_predicates.Count > 1)
                    {
                        CombineTwoPredicatesOnStack();
                    }
                }
                break;

            case "LastOrDefault":
            case "Last":
                ElementSelection  = "last";
                this.ThrowIfEmpty = methodName == "Last";
                if (methodCallExpr.Arguments.Count == 2)
                {
                    if (_predicates.Count > 1)
                    {
                        CombineTwoPredicatesOnStack();
                    }
                }
                break;

            case "ElementAtOrDefault":
            case "ElementAt":
                ElementSelection  = "elementat";
                this.ThrowIfEmpty = methodName == "ElementAt";
                var constExpr = GetArgumentAsConstant(methodCallExpr, 1);
                var index     = Convert.ToInt32(constExpr.Value);
                this.Skip = index;
                this.Top  = 1;
                break;

            case "Any":
                ElementSelection   = "first";
                this.CountOnly     = true;
                this.ExistenceOnly = true;
                this.Top           = 1;
                if (methodCallExpr.Arguments.Count == 2)
                {
                    if (_predicates.Count > 1)
                    {
                        CombineTwoPredicatesOnStack();
                    }
                }
                break;

            case "Type":
                var typeExpr = GetArgumentAsConstant(methodCallExpr, 0);
                BuildTextPredicate("Type", (string)typeExpr.Value);
                break;

            case "TypeIs":
                var typeIsExpr = GetArgumentAsConstant(methodCallExpr, 0);
                BuildTextPredicate("TypeIs", (string)(typeIsExpr).Value);
                break;

            case "get_Item":
                if (!(methodCallExpr.Object is ParameterExpression))
                {
                    throw new NotSupportedException("#get_Item");
                }
                break;

            case "startswith":
            {
                var fieldName      = GetPropertyName(methodCallExpr.Arguments[0]);
                var startswithExpr = GetArgumentAsConstant(methodCallExpr, 1);
                var arg            = (string)startswithExpr.Value;
                BuildWildcardPredicate(fieldName, WildcardPosition.AtEnd, arg);
                break;
            }

            case "endswith":
            {
                var fieldName    = GetPropertyName(methodCallExpr.Arguments[0]);
                var endswithExpr = GetArgumentAsConstant(methodCallExpr, 1);
                var arg          = (string)endswithExpr.Value;
                BuildWildcardPredicate(fieldName, WildcardPosition.AtStart, arg);
                break;
            }

            case "substringof":
            {
                var fieldName       = GetPropertyName(methodCallExpr.Arguments[1]);
                var substringofExpr = GetArgumentAsConstant(methodCallExpr, 0);
                var arg             = (string)substringofExpr.Value;
                BuildWildcardPredicate(fieldName, WildcardPosition.AtStartAndEnd, arg);
                break;
            }

            case "isof":
            {
                var isofExpr = GetArgumentAsConstant(methodCallExpr, 1);
                BuildTextPredicate("TypeIs", (string)(isofExpr).Value);
                break;
            }

            case "InFolder":
            {
                var infolderexpr = GetArgumentAsConstant(methodCallExpr, 0);
                var folder       = infolderexpr.Value;
                BuildTextPredicate("InFolder", GetPath(folder, "InFolder"));
                break;
            }

            case "InTree":
            {
                var intreeexpr = GetArgumentAsConstant(methodCallExpr, 0);
                var folder     = intreeexpr.Value;
                BuildTextPredicate("InTree", GetPath(folder, "InTree"));
                break;
            }

            case "GetType":
            {
                if (methodCallExpr.Object is MemberExpression member && member.Member == typeof(Content).GetProperty("ContentHandler"))
                {
                    _predicates.Push(new ContentHandlerGetTypePredicate());
                }