private void ParseNode <TKey, TAggregateRoot>(ParseTreeNode node, ref SortSpecification <TKey, TAggregateRoot> sortSpecification) where TKey : IEquatable <TKey> where TAggregateRoot : class, IAggregateRoot <TKey> { switch (node.Term.Name) { case "sort-specification": var suggestedPropertyName = node.ChildNodes[0].ChildNodes[0].Token.ValueString; var suggestedSortingOrder = node.ChildNodes[1].ChildNodes[0].Token.ValueString; var propertyName = ParsingUtils.InferProperty <TAggregateRoot>(suggestedPropertyName)?.Name; if (string.IsNullOrEmpty(propertyName)) { throw new ParsingException("Expression parsed failed.", new[] { $"The property that has the name similar to {suggestedPropertyName} does not exist." }); } var sortOrder = suggestedSortingOrder.ToUpper() == "A" ? SortOrder.Ascending : SortOrder.Descending; sortSpecification.Add(propertyName, sortOrder); break; case "concatenated-sort-specification": var leftNode = node.ChildNodes[0]; var rightNode = node.ChildNodes[2]; ParseNode(leftNode, ref sortSpecification); ParseNode(rightNode, ref sortSpecification); break; } }
public void ToString_FormatsInformatively() { var spec = new SortSpecification("SomeProp", SortDirection.Ascending); var formatted = spec.ToString(); Assert.Equal("SomeProp:Ascending", formatted); }
public SortSpecification <TAggregateRoot> Parse(string sorter) { var sortSpecification = new SortSpecification <TAggregateRoot>(); if (!string.IsNullOrWhiteSpace(sorter)) { sorter = sorter.Trim(); var sorts = sorter.Split(','); foreach (var sort in sorts) { var tokens = sort.Trim().Split(' '); if (tokens.Length == 1) { sortSpecification.Add(tokens[0].Trim(), SortDirection.Asc); } else if (tokens.Length == 2) { sortSpecification.Add(tokens[0].Trim(), ParseDirection(tokens[1])); } else { throw new Exception.SorterParseException(); } } } return(sortSpecification); }
public void ToString_NullParamsNoError() { var spec = new SortSpecification(null, SortDirection.Descending); var formatted = spec.ToString(); Assert.Equal("null:Descending", formatted); }
public virtual async Task <IActionResult> Get([FromQuery] int size = 15, [FromQuery] int page = 1, [FromQuery] string query = "", [FromQuery] string sort = "") { try { Expression <Func <TAggregateRoot, bool> > queryCondition = _ => true; if (!string.IsNullOrEmpty(query)) { queryCondition = this.queryConditionParser.Parse <TAggregateRoot>(query); } SortSpecification <TKey, TAggregateRoot> sortSpecification = new SortSpecification <TKey, TAggregateRoot> { { x => x.Id, SortOrder.Ascending } }; if (!string.IsNullOrEmpty(sort)) { sortSpecification = this.sortSpecificationParser.Parse <TKey, TAggregateRoot>(sort); } var aggregateRoots = await this.repository.FindAllAsync(queryCondition, sortSpecification, page, size); return(Ok(aggregateRoots)); } catch (ParsingException pe) { var parsingErrors = string.Join(Environment.NewLine, pe.ParseErrors); throw new InvalidArgumentException($"The specified query or sort is invalid. Details: {Environment.NewLine}{parsingErrors}", pe); } }
private void ApplySortInternal(SortSpecification sort) { if (this.FirstApplySortCall) { this.SortOrder.Clear(); this.FirstApplySortCall = false; } this.SortOrder.Add(sort); }
public virtual IQueryable <T> SortAndPage(IQueryable <T> data, SortSpecification sortSpecification, CurrentPageInformation pagingInfo) { string sort = null; if (sortSpecification != null && !string.IsNullOrWhiteSpace(sort = sortSpecification.ToString())) { return(Page(data.OrderBy(sort), pagingInfo)); } return(Page(data.OrderByDescending(DefaultOrderSelector()), pagingInfo)); }
public static SortSpecification <T> ToSpecification <T>(this ICollection <Sorter> sorters) { if (sorters == null || sorters.Count == 0) { return(SortSpecification <T> .None); } var spec = new SortSpecification <T>(); foreach (var sorter in sorters) { spec[sorter.Property] = sorter.SortOrder; } return(spec); }
public void AscNestedTest() { var sorts = new List <SortModel>(); var sort = new SortModel { FieldName = "Orders[Payment.Id]", Order = SortOrder.Asc }; sorts.Add(sort); var spec = SortSpecification <Customer> .Create(sorts); var expression = spec.ToExpression(); Assert.Equal("x.Orders.FirstOrDefault().Payment.Id", expression.Body.ToString()); }
public void BadTest() { var sorts = new List <SortModel>(); var sort = new SortModel { FieldName = "sdfsdf", Order = SortOrder.Asc }; sorts.Add(sort); var spec = SortSpecification <Customer> .Create(sorts); var expression = spec.ToExpression(); Assert.Equal("x", expression.Body.ToString()); }
private static IEnumerable <Customer> Sort(IEnumerable <Customer> origin, SortSpecification <int, Customer> sort) { var specs = sort.Specifications; if (specs.Count() > 0) { var first = specs.First(); var result = first.Item2 == SortOrder.Ascending ? origin.OrderBy(first.Item1.Compile()) : origin.OrderByDescending(first.Item1.Compile()); for (int i = 1; i < specs.Count(); i++) { var spec = specs.ElementAt(i); result = spec.Item2 == SortOrder.Ascending ? result.ThenBy(spec.Item1.Compile()) : result.ThenByDescending(spec.Item1.Compile()); } return(result); } return(origin); }
public SortSpecification <TKey, TAggregateRoot> Parse <TKey, TAggregateRoot>(string input) where TKey : IEquatable <TKey> where TAggregateRoot : class, IAggregateRoot <TKey> { var syntaxTree = parser.Parse(input); if (syntaxTree.HasErrors()) { var parseErrors = new List <string>(); syntaxTree.ParserMessages.ToList().ForEach(m => parseErrors.Add(m.ToString())); throw new ParsingException($"Input text '{input}' parsed failed. See ParseErrors property for more details.", parseErrors); } var sortSpecification = new SortSpecification <TKey, TAggregateRoot>(); ParseNode(syntaxTree.Root, ref sortSpecification); return(sortSpecification); }
public void ApplySorts_AppliesAllSorts(SortDirection dir, string expFirst1, string expFirst2) { var specs = new SortSpecification[] { new SortSpecification("Id", SortDirection.Ascending), new SortSpecification("First", dir), }; var available = new Dictionary <string, dynamic>() { { "Id", (Expression <Func <User, long> >)(u => u.Id) }, { "First", (Expression <Func <User, string> >)(u => u.First) } }; var factory = new SortFactory <User, long>(specs, available); var list = new List <User>() { new User() { Id = 3, First = expFirst1 }, new User() { Id = 3, First = expFirst2 }, new User() { Id = 1 }, new User() { Id = 4 } }.AsQueryable(); var sorted = factory.ApplySorts(list); Assert.Equal(1, sorted.First().Id); Assert.Equal(expFirst1, sorted.ElementAt(1).First); Assert.Equal(expFirst2, sorted.ElementAt(2).First); Assert.Equal(4, sorted.Last().Id); }
public override IQueryable <TEntity> Search(Specification <TEntity> filter, SortSpecification <TEntity> sorter, params string[] includes) { if (filter == null) { filter = Specification <TEntity> .Any(); } if (sorter == null) { sorter = SortSpecification <TEntity> .None; } var query = Context.Set <TEntity>().Where(filter); if (includes != null) { foreach (var include in includes) { query = query.Include(include); } } if (sorter.Count > 0) { var sorts = sorter.Specifications.ToList(); var orderedQuery = sorts[0].Item2 == SortDirection.Asc ? query.OrderBy(sorts[0].Item1) : query.OrderByDescending(sorts[0].Item1); for (var i = 1; i < sorts.Count; i++) { orderedQuery = sorts[i].Item2 == SortDirection.Asc ? orderedQuery.OrderBy(sorts[i].Item1) : orderedQuery.OrderByDescending(sorts[i].Item1); } query = orderedQuery; } return(query); }
/// <summary> /// Gets all the <see cref="T:Apworks.IAggregateRoot`1" /> instances from current repository according to a given query specification for /// the specified page size and page number that matches the given sorting specification. /// </summary> /// <param name="specification">The specification which specifies the query criteria.</param> /// <param name="sortSpecification">The specifications which implies the sorting.</param> /// <param name="pageNumber">The number of the page to be returned from the query.</param> /// <param name="pageSize">The number of records per page.</param> /// <param name="cancellationToken">The <see cref="T:System.Threading.CancellationToken" /> that propagates the notification that the operation should be cancelled.</param> /// <returns> /// The task that performs the querying and returns the <see cref="T:Apworks.Querying.PagedResult`2" /> instance which contains both /// query result and the pagination information. /// </returns> public virtual Task <PagedResult <TKey, TAggregateRoot> > FindAllAsync(Expression <Func <TAggregateRoot, bool> > specification, SortSpecification <TKey, TAggregateRoot> sortSpecification, int pageNumber, int pageSize, CancellationToken cancellationToken = default(CancellationToken)) { return(Task.FromResult(this.FindAll(specification, sortSpecification, pageNumber, pageSize))); }
/// <summary> /// Gets all the <see cref="T:Apworks.IAggregateRoot`1" /> instances from current repository according to a given query specification for /// the specified page size and page number that matches the given sorting specification. /// </summary> /// <param name="specification">The specification which specifies the query criteria.</param> /// <param name="sortSpecification">The specifications which implies the sorting.</param> /// <param name="pageNumber">The number of the page to be returned from the query.</param> /// <param name="pageSize">The number of records per page.</param> /// <returns> /// A <see cref="T:Apworks.Querying.PagedResult`2" /> instance which contains the returned objects and the pagination information. /// </returns> public abstract PagedResult <TKey, TAggregateRoot> FindAll(Expression <Func <TAggregateRoot, bool> > specification, SortSpecification <TKey, TAggregateRoot> sortSpecification, int pageNumber, int pageSize);
/// <summary> /// Gets all the <see cref="T:Apworks.IAggregateRoot`1" /> instances from current repository according to a given query specification with the sorting enabled. /// </summary> /// <param name="specification">The specification which specifies the query criteria.</param> /// <param name="sortSpecification">The specifications which implies the sorting.</param> /// <param name="cancellationToken">The <see cref="T:System.Threading.CancellationToken" /> that propagates the notification that the operation should be cancelled.</param> /// <returns> /// A <see cref="T:System.Linq.IEnumerable`1" /> instance which queries over the collection of the <see cref="T:Apworks.IAggregateRoot`1" /> objects. /// </returns> public virtual Task <IEnumerable <TAggregateRoot> > FindAllAsync(Expression <Func <TAggregateRoot, bool> > specification, SortSpecification <TKey, TAggregateRoot> sortSpecification, CancellationToken cancellationToken = default(CancellationToken)) { return(Task.FromResult(this.FindAll(specification, sortSpecification))); }
/// <summary> /// Gets all the <see cref="T:Apworks.IAggregateRoot`1" /> instances from current repository according to a given query specification with the sorting enabled. /// </summary> /// <param name="specification">The specification which specifies the query criteria.</param> /// <param name="sortSpecification">The specifications which implies the sorting.</param> /// <returns> /// A <see cref="T:System.Linq.IEnumerable`1" /> instance which queries over the collection of the <see cref="T:Apworks.IAggregateRoot`1" /> objects. /// </returns> public abstract IEnumerable <TAggregateRoot> FindAll(Expression <Func <TAggregateRoot, bool> > specification, SortSpecification <TKey, TAggregateRoot> sortSpecification);
public override IEnumerable <TAggregateRoot> FindAll(Expression <Func <TAggregateRoot, bool> > specification, SortSpecification <TKey, TAggregateRoot> sortSpecification) { var find = this.collection.Find(specification); if (sortSpecification == null) { return(find.ToEnumerable().AsQueryable()); } var sorts = sortSpecification.Specifications.ToList(); if (sorts.Any(s => s.Item2 == SortOrder.Unspecified)) { return(find.ToEnumerable().AsQueryable()); } var firstSort = sorts[0]; IOrderedFindFluent <TAggregateRoot, TAggregateRoot> orderedFind = firstSort.Item2 == SortOrder.Ascending ? find.SortBy(firstSort.Item1) : find.SortByDescending(firstSort.Item1); for (var i = 1; i < sorts.Count; i++) { var current = sorts[i]; orderedFind = current.Item2 == SortOrder.Ascending ? orderedFind.SortBy(current.Item1) : orderedFind.SortByDescending(current.Item1); } return(orderedFind.ToEnumerable().AsQueryable()); }
public override async Task <PagedResult <TKey, TAggregateRoot> > FindAllAsync(Expression <Func <TAggregateRoot, bool> > specification, SortSpecification <TKey, TAggregateRoot> sortSpecification, int pageNumber, int pageSize, CancellationToken cancellationToken = default(CancellationToken)) { if (specification == null) { specification = _ => true; } if (sortSpecification == null) { throw new ArgumentNullException(nameof(sortSpecification), "The sort specification has not been specified."); } if (pageNumber <= 0) { throw new ArgumentOutOfRangeException(nameof(pageNumber), "The page number should be greater than 0."); } if (pageSize <= 0) { throw new ArgumentOutOfRangeException(nameof(pageSize), "The page size should be greater than 0."); } var sortDefinitions = new List <SortDefinition <TAggregateRoot> >(); foreach (var sort in sortSpecification.Specifications) { sortDefinitions.Add(sort.Item2 == SortOrder.Ascending ? Builders <TAggregateRoot> .Sort.Ascending(sort.Item1) : Builders <TAggregateRoot> .Sort.Descending(sort.Item1)); } var totalCount = await this.collection.CountAsync(specification); var skip = (pageNumber - 1) * pageSize; var take = pageSize; var totalPages = (totalCount + pageSize - 1) / pageSize; var aggregatedSortDefinition = Builders <TAggregateRoot> .Sort.Combine(sortDefinitions); var findOptions = new FindOptions <TAggregateRoot> { Sort = aggregatedSortDefinition, Skip = skip, Limit = take }; return(new PagedResult <TKey, TAggregateRoot>((await this.collection.FindAsync <TAggregateRoot>(specification, findOptions)).ToEnumerable(), pageNumber, pageSize, totalCount, totalPages)); }
/// <summary> /// Gets all the <see cref="T:Apworks.IAggregateRoot`1" /> instances from current repository according to a given query specification with the sorting enabled. /// </summary> /// <param name="specification">The specification which specifies the query criteria.</param> /// <param name="sortSpecification">The specifications which implies the sorting.</param> /// <returns> /// A <see cref="T:System.Linq.IEnumerable`1" /> instance which queries over the collection of the <see cref="T:Apworks.IAggregateRoot`1" /> objects. /// </returns> public override IEnumerable <TAggregateRoot> FindAll(Expression <Func <TAggregateRoot, bool> > specification, SortSpecification <TKey, TAggregateRoot> sortSpecification) { if (specification == null) { specification = _ => true; } var query = this.context.Session.Values.Select(x => (TAggregateRoot)x).Where(specification.Compile()); if (sortSpecification?.Count > 0) { IOrderedEnumerable <TAggregateRoot> orderedQuery = null; foreach (var sort in sortSpecification.Specifications) { if (orderedQuery == null) { orderedQuery = sort.Item2 == SortOrder.Descending ? query.OrderByDescending(sort.Item1.Compile()) : query.OrderBy(sort.Item1.Compile()); } else { orderedQuery = sort.Item2 == SortOrder.Descending ? orderedQuery.OrderByDescending(sort.Item1.Compile()) : orderedQuery.OrderBy(sort.Item1.Compile()); } } return(orderedQuery); } return(query); }
public override async Task <IEnumerable <TAggregateRoot> > FindAllAsync(Expression <Func <TAggregateRoot, bool> > specification, SortSpecification <TKey, TAggregateRoot> sortSpecification, CancellationToken cancellationToken = default(CancellationToken)) { if (sortSpecification == null || sortSpecification.Specifications == null || sortSpecification.Specifications.Count() == 0) { return((await this.collection.FindAsync(specification, cancellationToken: cancellationToken)) .ToEnumerable(cancellationToken) .AsQueryable()); } var sorts = sortSpecification.Specifications.ToList(); if (sorts.Any(s => s.Item2 == SortOrder.Unspecified)) { return((await this.collection.FindAsync(specification, cancellationToken: cancellationToken)) .ToEnumerable(cancellationToken) .AsQueryable()); } var sortDefinitions = new List <SortDefinition <TAggregateRoot> >(); foreach (var sort in sorts) { sortDefinitions.Add(sort.Item2 == SortOrder.Ascending ? Builders <TAggregateRoot> .Sort.Ascending(sort.Item1) : Builders <TAggregateRoot> .Sort.Descending(sort.Item1)); } var aggregatedSortDefinition = Builders <TAggregateRoot> .Sort.Combine(sortDefinitions); var findOptions = new FindOptions <TAggregateRoot> { Sort = aggregatedSortDefinition }; return((await this.collection.FindAsync(specification, findOptions, cancellationToken)) .ToEnumerable(cancellationToken) .AsQueryable()); }
/// <summary> /// Creates a statement. /// </summary> /// <returns></returns> public override SqlStatement GetStatement() { if (EntityType == null) { throw new ArgumentNullException("EntityType"); } // mbr - 16-10-2005 - changed so that inheriting classes can override default field inclusion behaviour... EntityField[] fields = this.ResolveFieldsForSelect(); if (fields == null) { throw new ArgumentNullException("fields"); } if (fields.Length == 0) { throw new InvalidOperationException("No fields selected."); } // create a statement... if (Dialect == null) { throw new ArgumentNullException("Dialect"); } SqlStatement statement = new SqlStatement(this.EntityType, this.Dialect); if (this.TimeoutSeconds > 0) { statement.TimeoutSeconds = this.TimeoutSeconds; } // set... statement.SetOriginalCreator(this); // check... if (statement.SelectMap == null) { throw new ArgumentNullException("statement.SelectMap"); } // set up the basic select text... StringBuilder builder = new StringBuilder(); builder.Append(statement.Dialect.SelectKeyword); // mbr - 2010-03-03 - added... if (this.Distinct) { builder.Append(" "); builder.Append(statement.Dialect.DistinctKeyword); } // top... if (this.Top > 0 && statement.Dialect.TopAtTop) { builder.Append(" "); builder.Append(statement.Dialect.FormatTop(this.Top)); } // fields... builder.Append(" "); for (int index = 0; index < fields.Length; index++) { // add... if (index > 0) { builder.Append(statement.Dialect.IdentifierSeparator); } // field... EntityField field = fields[index]; if (field.IsExtendedProperty) { // mbr - 25-09-2007 - provider... // AppendExtendedPropertyStatement(statement, builder, field); if (Database.ExtensibilityProvider == null) { throw new InvalidOperationException("Database.ExtensibilityProvider is null."); } Database.ExtensibilityProvider.AddExtendedPropertyToSelectStatement(this, statement, builder, field); } else { // mbr - 2008-09-11 - changed for MySQL support... // builder.Append(statement.Dialect.FormatColumnName(field, this.UseFullyQualifiedNames)); builder.Append(statement.Dialect.FormatColumnNameForSelect(field, this.UseFullyQualifiedNames)); // mbr - 10-10-2007 - case 875 - do nothing if we don't have a join... if (field.EntityType == this.EntityType) { statement.SelectMap.MapFields.Add(new SelectMapField(field, index)); } else { // find it! SqlJoin found = null; foreach (SqlJoin join in this.Joins) { if (join.TargetEntityType == field.EntityType) { found = join; break; } } // found? if (found == null) { throw new InvalidOperationException(string.Format("Could not find a join for field '{0}'.", field)); } // set... statement.SelectMap.MapFields.Add(new SelectMapField(field, index, found)); } } } this.AppendIndent(builder); builder.Append(statement.Dialect.FromKeyword); builder.Append(" "); builder.Append(statement.Dialect.FormatTableName(this.EntityType.NativeName)); if (this.HasForcedIndex) { builder.Append(" "); builder.Append(statement.Dialect.GetForceIndexDirective(this.ForcedIndex)); } // mbr - 25-09-2007 - joins... this.AppendJoins(statement, builder); // get the contraints... StringBuilder constraints = new StringBuilder(); this.AppendConstraints(statement, constraints); // trim... string useConstraints = constraints.ToString().Trim(); //// mbr - 13-10-2005 - rejigged to handle partitioning... //// mbr - 08-03-2006 - added supports... // mbr - 2014-11-30 - removes partitioning... //if(!(this.IgnorePartitioning) && this.EntityType.SupportsPartitioning) //{ // // get the strategy.... // PartitioningStrategy strategy = this.EntityType.PartitioningStrategy; // if(strategy == null) // throw new InvalidOperationException("strategy is null."); // // get the partition SQL... // // mbr - 04-09-2007 - c7 - removed 'forReading'. // // useConstraints = strategy.RebuildConstraints(statement, useConstraints, true); // useConstraints = strategy.RebuildConstraints(statement, useConstraints); // // we have to get something back... // if(useConstraints == null) // throw new InvalidOperationException("'useConstraints' is null."); // // mbr - 04-09-2007 - for c7 - a zero-length string might be ok... // if(useConstraints.Length == 0 && !(strategy.IsZeroLengthIdSetOk)) // throw new InvalidOperationException("'useConstraints' is zero-length."); //} // mbr - 2010-03-10 - added a method to allow us to change the statement before it is executed... if (Database.StatementCallback != null) { useConstraints = Database.StatementCallback.ReplaceContraints(statement, this, useConstraints); } // do we have constraints? if (useConstraints.Length > 0) { // just add the constraints... this.AppendIndent(builder); builder.Append(this.Dialect.WhereKeyword); builder.Append(" "); builder.Append(useConstraints); } // mbr - 2010-03-08 - if not distinct... ///if (this.SortOrder.Count > 0) //if ((!(this.Distinct) || this.ForceSortOnDistinct) && this.SortOrder.Count > 0) // mbr - 2016-08-17 -- no idea why this was like this... if (this.SortOrder.Count > 0) { // append... this.AppendIndent(builder); builder.Append(statement.Dialect.OrderByKeyword); builder.Append(" "); // add... for (int index = 0; index < this.SortOrder.Count; index++) { if (index > 0) { builder.Append(statement.Dialect.IdentifierSeparator); } // spec... SortSpecification specification = this.SortOrder[index]; // mbr - 10-10-2007 - case 875 - fixed to qualify... // builder.Append(statement.Dialect.FormatNativeName(specification.Field.NativeName)); if (specification.Field != null) { builder.Append(statement.Dialect.FormatColumnName(specification.Field, this.UseFullyQualifiedNames)); } else { builder.Append(specification.FreeSort); } // direction? builder.Append(" "); builder.Append(statement.Dialect.GetSortDirectionKeyword(specification.Direction)); } } // top... if (this.Top > 0 && !(statement.Dialect.TopAtTop)) { this.AppendIndent(builder); builder.Append(statement.Dialect.FormatTop(this.Top)); } if (this.SignalRecompile) { builder.Append(" OPTION(RECOMPILE)"); } // setup... statement.CommandText = builder.ToString(); statement.CommandType = CommandType.Text; // extras... statement.Parameters.AddRange(this.ExtraParameters); // return... return(statement); }
public virtual IEnumerable <T> Filter(TFilterDefinition filterDefinition, CurrentPageInformation pagingInfo, SortSpecification sortSpecification, out int count) { var data = PrepareFilter(filterDefinition); count = data.Count(); return(SortAndPage(data, sortSpecification, pagingInfo)); }
public override IEnumerable <TAggregateRoot> FindAll(Expression <Func <TAggregateRoot, bool> > specification, SortSpecification <TKey, TAggregateRoot> sortSpecification) { var query = this.dbContext.Set <TAggregateRoot>().Where(specification); if (sortSpecification?.Count > 0) { IOrderedQueryable <TAggregateRoot> orderedQuery = null; (from sort in sortSpecification.Specifications where sort.Item2 != SortOrder.Unspecified select sort) .ToList() .ForEach(sort => { switch (sort.Item2) { case SortOrder.Ascending: orderedQuery = orderedQuery == null ? query.OrderBy(sort.Item1) : orderedQuery.OrderBy(sort.Item1); break; case SortOrder.Descending: orderedQuery = orderedQuery == null ? query.OrderByDescending(sort.Item1) : orderedQuery.OrderByDescending(sort.Item1); break; } }); return(orderedQuery); } return(query); }
public override PagedResult <TKey, TAggregateRoot> FindAll(Expression <Func <TAggregateRoot, bool> > specification, SortSpecification <TKey, TAggregateRoot> sortSpecification, int pageNumber, int pageSize) { if (specification == null) { specification = _ => true; } if (sortSpecification?.Count == 0) { throw new ArgumentNullException(nameof(sortSpecification), "The sort specification has not been specified."); } if (pageNumber <= 0) { throw new ArgumentOutOfRangeException(nameof(pageNumber), "The page number should be greater than 0."); } if (pageSize <= 0) { throw new ArgumentOutOfRangeException(nameof(pageSize), "The page size should be greater than 0."); } var sorts = sortSpecification.Specifications.ToList(); if (sorts.Any(s => s.Item2 == SortOrder.Unspecified)) { throw new InvalidOperationException("The SortOrder of the items in the sort specification should be either Ascending or Descending."); } var query = this.dbContext.Set <TAggregateRoot>().Where(specification); var total = query.Count(); if (total == 0) { return(PagedResult <TKey, TAggregateRoot> .CreateDefault(pageNumber, pageSize)); } var skip = (pageNumber - 1) * pageSize; var take = pageSize; IOrderedQueryable <TAggregateRoot> orderedQuery = null; foreach (var sort in sorts) { switch (sort.Item2) { case SortOrder.Ascending: orderedQuery = orderedQuery == null?query.OrderBy(sort.Item1) : orderedQuery.OrderBy(sort.Item1); break; case SortOrder.Descending: orderedQuery = orderedQuery == null?query.OrderByDescending(sort.Item1) : orderedQuery.OrderByDescending(sort.Item1); break; } } //var pagedQuery = orderedQuery.Skip(skip).Take(take).GroupBy(p => new { Total = total }).FirstOrDefault(); //return pagedQuery == null ? null : // new PagedResult<TKey, TAggregateRoot>(pagedQuery.Select(_ => _), pageNumber, pageSize, pagedQuery.Key.Total, (pagedQuery.Key.Total + pageSize - 1) / pageSize); var pagedQuery = orderedQuery.Skip(skip).Take(take); return(pagedQuery == null ? null : new PagedResult <TKey, TAggregateRoot>(pagedQuery, pageNumber, pageSize, total, (total + pageSize - 1) / pageSize)); }
/// <summary> /// Gets all the <see cref="T:Apworks.IAggregateRoot`1" /> instances from current repository for the specified page size and page number that matches the given sorting specification. /// </summary> /// <param name="sortSpecification">The sort specification.</param> /// <param name="pageNumber">The number of the page to be returned from the query.</param> /// <param name="pageSize">The number of records per page.</param> /// <returns> /// A <see cref="T:Apworks.Querying.PagedResult`2" /> instance which contains the returned objects and the pagination information. /// </returns> public virtual PagedResult <TKey, TAggregateRoot> FindAll(SortSpecification <TKey, TAggregateRoot> sortSpecification, int pageNumber, int pageSize) { return(this.FindAll(_ => true, sortSpecification, pageNumber, pageSize)); }
public override PagedResult <TKey, TAggregateRoot> FindAll(Expression <Func <TAggregateRoot, bool> > specification, SortSpecification <TKey, TAggregateRoot> sortSpecification, int pageNumber, int pageSize) { if (specification == null) { specification = _ => true; } if (sortSpecification?.Count == 0) { throw new ArgumentNullException(nameof(sortSpecification), "The sort specification has not been specified."); } if (pageNumber <= 0) { throw new ArgumentOutOfRangeException(nameof(pageNumber), "The page number should be greater than 0."); } if (pageSize <= 0) { throw new ArgumentOutOfRangeException(nameof(pageSize), "The page size should be greater than 0."); } var sorts = sortSpecification.Specifications.ToList(); if (sorts.Any(s => s.Item2 == SortOrder.Unspecified)) { throw new InvalidOperationException("The SortOrder of the items in the sort specification should be either Ascending or Descending."); } var totalCount = this.collection.Count(specification); var skip = (pageNumber - 1) * pageSize; var take = pageSize; var totalPages = (totalCount + pageSize - 1) / pageSize; var find = this.collection.Find(specification); var firstSort = sorts[0]; var orderedFind = firstSort.Item2 == SortOrder.Ascending ? find.SortBy(firstSort.Item1) : find.SortByDescending(firstSort.Item1); for (var i = 1; i < sorts.Count; i++) { var current = sorts[i]; orderedFind = current.Item2 == SortOrder.Ascending ? orderedFind.SortBy(current.Item1) : orderedFind.SortByDescending(current.Item1); } return(new PagedResult <TKey, TAggregateRoot>(find.Skip(skip).Limit(take).ToEnumerable(), pageNumber, pageSize, totalCount, totalPages)); }
/// <summary> /// Gets all the <see cref="T:Apworks.IAggregateRoot`1" /> instances from current repository for the specified page size and page number that matches the given sorting specification asynchronously. /// </summary> /// <param name="sortSpecification">The sort specification.</param> /// <param name="pageNumber">The number of the page to be returned from the query.</param> /// <param name="pageSize">The number of records per page.</param> /// <param name="cancellationToken">The <see cref="T:System.Threading.CancellationToken" /> that propagates the notification that the operation should be cancelled.</param> /// <returns> /// The task that performs the querying and returns the <see cref="T:Apworks.Querying.PagedResult`2" /> instance which contains both /// query result and the pagination information. /// </returns> public virtual Task <PagedResult <TKey, TAggregateRoot> > FindAllAsync(SortSpecification <TKey, TAggregateRoot> sortSpecification, int pageNumber, int pageSize, CancellationToken cancellationToken = default(CancellationToken)) { return(this.FindAllAsync(_ => true, sortSpecification, pageNumber, pageSize, cancellationToken)); }
public override PagedResult <TKey, TAggregateRoot> FindAll(Expression <Func <TAggregateRoot, bool> > specification, SortSpecification <TKey, TAggregateRoot> sortSpecification, int pageNumber, int pageSize) { if (specification == null) { specification = _ => true; } if (sortSpecification?.Count == 0) { throw new ArgumentNullException(nameof(sortSpecification), "The sort specification has not been specified."); } if (pageNumber <= 0) { throw new ArgumentOutOfRangeException(nameof(pageNumber), "The page number should be greater than 0."); } if (pageSize <= 0) { throw new ArgumentOutOfRangeException(nameof(pageSize), "The page size should be greater than 0."); } var sorts = sortSpecification.Specifications.ToList(); if (sorts.Any(s => s.Item2 == SortOrder.Unspecified)) { throw new InvalidOperationException("The SortOrder of the items in the sort specification should be either Ascending or Descending."); } var query = this.context.Session.Values.Select(x => (TAggregateRoot)x).Where(specification.Compile()); var totalCount = query.Count(); var skip = (pageNumber - 1) * pageSize; var take = pageSize; var totalPages = (totalCount + pageSize - 1) / pageSize; IOrderedEnumerable <TAggregateRoot> orderedQuery = null; foreach (var sort in sorts) { if (orderedQuery == null) { orderedQuery = sort.Item2 == SortOrder.Descending ? query.OrderByDescending(sort.Item1.Compile()) : query.OrderBy(sort.Item1.Compile()); } else { orderedQuery = sort.Item2 == SortOrder.Descending ? orderedQuery.OrderByDescending(sort.Item1.Compile()) : orderedQuery.OrderBy(sort.Item1.Compile()); } } return(new PagedResult <TKey, TAggregateRoot>(orderedQuery.Skip(skip).Take(take), pageNumber, pageSize, totalCount, totalPages)); }