Exemple #1
0
        public IQueryCommand Translate(Expression expression)
        {
            expression       = Evaluator.PartialEval(expression);
            _sb              = new StringBuilder();
            _sbCustomFilter  = new StringBuilder();
            _expressionStack = new Stack <ExpressionType>();
            Visit(expression);

            if (_commandOptions == null)
            {
                if (IsDynamic)
                {
                    _commandOptions = new DynamicQueryCommandOptions();
                }
                else
                {
                    _commandOptions = new StandardQueryCommandOptions(_mapping, _mapping.Properties);
                }
            }

            if ((_falseEncountered && _sb.Length == 0) == false)
            {
                string filter;
                if (_pagingFilter == null)
                {
                    string ocFilter = GetOcFilter();
                    if (_sb.Length == 0)
                    {
                        filter = ocFilter;
                    }
                    else
                    {
                        if (!string.IsNullOrEmpty(ocFilter))
                        {
                            filter = $"(&{ocFilter}{_sb})";
                        }
                        else
                        {
                            filter = _exclusiveWhereCount > 1
                                ? $"(&{_sb})"
                                : $"{_sb}";
                        }
                    }

                    if (_customFiltersCount > 0)
                    {
                        var customFilter = _customFiltersCount > 1
                            ? $"(&{_sbCustomFilter})"
                            : _sbCustomFilter.ToString();

                        filter = filter.IsNullOrEmpty()
                            ? customFilter
                            : $"(&{customFilter}{filter})";
                    }
                }
                else
                {
                    filter = _pagingFilter;
                }

                _commandOptions.Filter = filter;
            }
            else
            {
                _commandOptions.YieldNoResults = true;
            }

            if ((_pagingOptions != null || (_controls?.Find(x => x is PageResultRequestControl) != null)) && _skipSize.HasValue)
            {
                throw new InvalidOperationException("Skip relies on Virtual List Views and cannot be used with simple LDAP paging. Please use one method for paging.");
            }

            _commandOptions.WithoutPaging  = _withoutPaging;
            _commandOptions.PagingOptions  = _pagingOptions;
            _commandOptions.SortingOptions = _sortingOptions;
            _commandOptions.PageSize       = _toListPageSize;
            _commandOptions.TakeSize       = _takeSize;
            _commandOptions.SkipSize       = _skipSize;
            _commandOptions.Controls       = _controls;
            _commandOptions.IsLongCount    = _isLongCount;

            var queryCommand = QueryCommandFactory.GetCommand(_commandType, _commandOptions, _mapping);

            return(queryCommand);
        }
Exemple #2
0
        private void VisitQueryableMethods(MethodCallExpression m)
        {
            switch (m.Method.Name)
            {
            case "Where":
                _exclusiveWhereCount++;
                foreach (Expression t in m.Arguments)
                {
                    Visit(t);
                }
                _commandType = QueryCommandType.StandardCommand;
                break;

            case "WithoutPaging":
                foreach (Expression t in m.Arguments)
                {
                    Visit(t);
                }
                _commandType   = QueryCommandType.StandardCommand;
                _withoutPaging = true;
                break;

            case "GetRequest":
                foreach (Expression t in m.Arguments)
                {
                    Visit(t);
                }
                _commandType = QueryCommandType.GetRequestCommand;
                break;

            case "Any":
                if (m.Arguments.Count > 1)
                {
                    _exclusiveWhereCount++;
                }
                foreach (Expression t in m.Arguments)
                {
                    Visit(t);
                }
                _commandType = QueryCommandType.AnyCommand;
                break;

            case "FirstOrDefault":
            case "First":
                if (m.Arguments.Count > 1)
                {
                    _exclusiveWhereCount++;
                }
                foreach (Expression t in m.Arguments)
                {
                    Visit(t);
                }
                _commandType = QueryCommandType.FirstOrDefaultCommand;
                break;

            case "SingleOrDefault":
                if (m.Arguments.Count > 1)
                {
                    _exclusiveWhereCount++;
                }
                foreach (Expression t in m.Arguments)
                {
                    Visit(t);
                }
                _commandType = QueryCommandType.SingleOrDefaultCommand;
                break;

            case "Single":
                if (m.Arguments.Count > 1)
                {
                    _exclusiveWhereCount++;
                }
                foreach (Expression t in m.Arguments)
                {
                    Visit(t);
                }
                _commandType = QueryCommandType.SingleCommand;
                break;

            case "LongCount":
            case "Count":
                _isLongCount = m.Method.Name == "LongCount";
                if (m.Arguments.Count > 1)
                {
                    _exclusiveWhereCount++;
                }
                foreach (Expression t in m.Arguments)
                {
                    Visit(t);
                }
                _commandType = QueryCommandType.CountCommand;
                break;

            case "ListAttributes":
                Dictionary <string, string> attributes = null;
                foreach (Expression t in m.Arguments)
                {
                    if (t.Type == typeof(string[]))
                    {
                        attributes = (((ConstantExpression)t).Value as string[]).ToDictionary(s => s);
                    }
                    else
                    {
                        Visit(t);
                    }
                }
                _commandOptions = new ListAttributesQueryCommandOptions(attributes);
                _commandType    = QueryCommandType.StandardCommand;
                break;

            case "FilterWith":
                foreach (Expression t in m.Arguments)
                {
                    if (t.Type == typeof(string))
                    {
                        _sbCustomFilter.Append(((ConstantExpression)t).Value.ToString());
                        _customFiltersCount++;
                    }
                    else
                    {
                        Visit(t);
                    }
                }
                _commandType = QueryCommandType.StandardCommand;
                break;

            case "Select":
                foreach (Expression t in m.Arguments)
                {
                    var lambda = StripQuotes(t) as LambdaExpression;
                    if (lambda != null)
                    {
                        if (_commandOptions != null)
                        {
                            throw new FilterException("Cannot have multiple Select projections.");
                        }

                        if (IsDynamic)
                        {
                            var projection = new DynamicSelectProjector(_mapping.Properties)
                                             .ProjectProperties(lambda);

                            _commandOptions = new DynamicQueryCommandOptions(projection);
                        }
                        else
                        {
                            var projection = new SelectProjector(_mapping.Properties)
                                             .ProjectProperties(lambda);
                            _commandOptions = new ProjectionQueryCommandOptions(_mapping, projection);
                        }
                    }
                    else if (t.Type == typeof(string[]))
                    {
                        if (!IsDynamic)
                        {
                            throw new FilterException(
                                      "Cannot use a string attribute projection with a static type.");
                        }
                        if (_commandOptions != null)
                        {
                            throw new FilterException("Cannot have multiple Select projections.");
                        }
                        _commandOptions =
                            new DynamicQueryCommandOptions(((ConstantExpression)t).Value as string[]);
                    }
                    else
                    {
                        Visit(t);
                    }
                }
                _commandType = QueryCommandType.StandardCommand;
                break;

            case "ToPage":
                int    pageSize = 0;
                byte[] nextPage = null;
                foreach (Expression t in m.Arguments)
                {
                    if (t.Type == typeof(int))
                    {
                        pageSize = (int)((ConstantExpression)t).Value;
                    }
                    else if (t.Type == typeof(byte[]))
                    {
                        nextPage = (byte[])((ConstantExpression)t).Value;
                    }
                    else if (t.Type == typeof(string))
                    {
                        _pagingFilter = (string)((ConstantExpression)t).Value;
                    }
                    else
                    {
                        Visit(t);
                    }
                }
                _pagingOptions = new PagingOptions(pageSize, nextPage);
                break;

            case "InPagesOf":
                foreach (Expression t in m.Arguments)
                {
                    if (t.Type == typeof(int))
                    {
                        _toListPageSize = (int)((ConstantExpression)t).Value;
                    }
                    else
                    {
                        Visit(t);
                    }
                }
                _commandType = QueryCommandType.StandardCommand;
                break;

            case "ToList":
                foreach (Expression t in m.Arguments)
                {
                    Visit(t);
                }
                _commandType = QueryCommandType.StandardCommand;
                break;

            case "Take":
                int takeAmount = 0;
                foreach (Expression t in m.Arguments)
                {
                    if (t.Type == typeof(int))
                    {
                        takeAmount = (int)((ConstantExpression)t).Value;
                    }
                    else
                    {
                        Visit(t);
                    }
                }
                _takeSize = takeAmount;
                break;

            case "Skip":
                int skipAmount = 0;
                foreach (Expression t in m.Arguments)
                {
                    if (t.Type == typeof(int))
                    {
                        skipAmount = (int)((ConstantExpression)t).Value;
                    }
                    else
                    {
                        Visit(t);
                    }
                }
                if (skipAmount < 0)
                {
                    throw new ArgumentException("Skip value must be greater than zero.");
                }
                _skipSize = skipAmount;
                break;

            case "WithControls":
                if (_controls == null)
                {
                    _controls = new List <DirectoryControl>();
                }
                foreach (Expression t in m.Arguments)
                {
                    IEnumerable <DirectoryControl> controls;
                    if (t is ConstantExpression && (controls = ((ConstantExpression)t).Value as IEnumerable <DirectoryControl>) != null)
                    {
                        _controls.AddRange(controls);
                    }
                    else
                    {
                        Visit(t);
                    }
                }
                break;

            case "OrderByDescending":
            case "ThenByDescending":
                string descRule = null;
                if (_sortingOptions == null)
                {
                    _sortingOptions = new SortingOptions();
                }
                foreach (Expression t in m.Arguments)
                {
                    var lambda = StripQuotes(t) as LambdaExpression;
                    if (lambda != null)
                    {
                        var attribute = GetMemberName((MemberExpression)lambda.Body);
                        _sortingOptions.AddSort(attribute, true);
                    }
                    else if (t.Type == typeof(string))
                    {
                        if (m.Arguments.IndexOf(t) == 1)
                        {
                            _sortingOptions.AddSort(((ConstantExpression)t).Value.ToString(), true);
                        }
                        else
                        {
                            descRule = ((ConstantExpression)t).Value.ToString();
                        }
                    }
                    else
                    {
                        Visit(t);
                    }
                }
                _sortingOptions.SetMatchingRule(descRule);
                break;

            case "OrderBy":
            case "ThenBy":
                if (_sortingOptions == null)
                {
                    _sortingOptions = new SortingOptions();
                }
                string ascRule = null;
                foreach (Expression t in m.Arguments)
                {
                    var lambda = StripQuotes(t) as LambdaExpression;
                    if (lambda != null)
                    {
                        var attribute = GetMemberName((MemberExpression)lambda.Body);
                        _sortingOptions.AddSort(attribute, false);
                    }
                    else if (t.Type == typeof(string))
                    {
                        if (m.Arguments.IndexOf(t) == 1)
                        {
                            _sortingOptions.AddSort(((ConstantExpression)t).Value.ToString(), false);
                        }
                        else
                        {
                            ascRule = ((ConstantExpression)t).Value.ToString();
                        }
                    }
                    else
                    {
                        Visit(t);
                    }
                }
                _sortingOptions.SetMatchingRule(ascRule);
                break;

            case "IgnoreOC":
                foreach (Expression t in m.Arguments)
                {
                    if (t.Type == typeof(OC))
                    {
                        _ignoreOc = (OC)((ConstantExpression)t).Value;
                    }
                    else
                    {
                        Visit(t);
                    }
                }
                break;

            case "IncludeOC":
                foreach (Expression t in m.Arguments)
                {
                    if (t.Type == typeof(OC))
                    {
                        _includeOc = (OC)((ConstantExpression)t).Value;
                    }
                    else
                    {
                        Visit(t);
                    }
                }
                break;
            }
        }