Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add new method to support pagination #57

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
385f0f4
add new method to support pagination
Jun 26, 2021
3217fa6
Update Microsoft.Azure.CosmosRepository/src/DefaultRepository.cs
zhangzunke Jun 27, 2021
7b2dc38
Update Microsoft.Azure.CosmosRepository/src/Dtos/PagedResult.cs
zhangzunke Jun 27, 2021
4fe5cd5
Update Microsoft.Azure.CosmosRepository/src/Dtos/PagedResult.cs
zhangzunke Jun 27, 2021
ba56ad3
Update Microsoft.Azure.CosmosRepository/src/Dtos/PagedResult.cs
zhangzunke Jun 27, 2021
ef067a3
Update Microsoft.Azure.CosmosRepository/src/Dtos/PagedResult.cs
zhangzunke Jun 27, 2021
77c6cf4
Update Microsoft.Azure.CosmosRepository/src/Dtos/PagedResultRequest.cs
zhangzunke Jun 27, 2021
60689cd
Update Microsoft.Azure.CosmosRepository/src/IRepository.cs
zhangzunke Jun 27, 2021
7ead3e2
Update Microsoft.Azure.CosmosRepository/src/IRepository.cs
zhangzunke Jun 27, 2021
cc61258
Update Microsoft.Azure.CosmosRepository/src/Dtos/ListResult.cs
zhangzunke Jun 27, 2021
5cf3c47
Update Microsoft.Azure.CosmosRepository/src/Dtos/IPagedResultRequest.cs
zhangzunke Jun 27, 2021
4d9b49c
Update Microsoft.Azure.CosmosRepository/src/Dtos/ILimitedResultReques…
zhangzunke Jun 27, 2021
03f60a3
Update Microsoft.Azure.CosmosRepository/src/DefaultRepository.cs
zhangzunke Jun 27, 2021
5f362d8
Update Microsoft.Azure.CosmosRepository/src/DefaultRepository.cs
zhangzunke Jun 27, 2021
47a70c1
Update Microsoft.Azure.CosmosRepository/src/Dtos/ListResult.cs
zhangzunke Jun 27, 2021
b498ee7
Update Microsoft.Azure.CosmosRepository/src/Dtos/ListResult.cs
zhangzunke Jun 27, 2021
2bd7919
Update Microsoft.Azure.CosmosRepository/src/Dtos/ListResult.cs
zhangzunke Jun 27, 2021
0daa747
Update Microsoft.Azure.CosmosRepository/src/Dtos/LimitedResultRequest.cs
zhangzunke Jun 27, 2021
2e1077a
update according to suggestion and add a sample app usage.
Jun 27, 2021
e7c4e32
adding an interface for skip
Jul 6, 2021
6709907
remove unused code
Jul 6, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Microsoft.Azure.CosmosRepository.Samples/ServiceTier/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Threading.Tasks;
using Microsoft.Azure.Cosmos;
using Microsoft.Azure.CosmosRepository;
using Microsoft.Azure.CosmosRepository.Pagination;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
Expand Down Expand Up @@ -93,6 +94,15 @@ static async Task RawRepositoryExampleAsync(IRepository<Person> repository)
Console.WriteLine($"[Person] Updated: {person}");
}

// Pagination read / verify pagination read
PagedResultRequest pagedResultRequest = new PagedResultRequest { SkipCount = 0, MaxResultCount = 2 };
PagedResult<Person> peopleWithPagedResult = await repository.GetListAsync(p => p.BirthDate > new DateTime(1970, 7, 21), pagedResultRequest);
Console.WriteLine($"[Person] Total Count: {peopleWithPagedResult.TotalCount}");
foreach (Person person in peopleWithPagedResult.Items)
{
Console.WriteLine($"[Person] Pagination Read: {person}");
}

// Deleting...
Console.WriteLine("[Person] Repository deleting...");
await Task.WhenAll(new[]
Expand Down
62 changes: 61 additions & 1 deletion Microsoft.Azure.CosmosRepository/src/DefaultRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Threading.Tasks;
using Microsoft.Azure.Cosmos;
using Microsoft.Azure.Cosmos.Linq;
using Microsoft.Azure.CosmosRepository.Pagination;
using Microsoft.Azure.CosmosRepository.Extensions;
using Microsoft.Azure.CosmosRepository.Options;
using Microsoft.Azure.CosmosRepository.Providers;
Expand Down Expand Up @@ -98,6 +99,65 @@ public async ValueTask<IEnumerable<TItem>> GetAsync(
return results;
}

/// <inheritdoc/>
public async Task<PagedResult<TItem>> GetListAsync<TPagedRequest>(
Expression<Func<TItem, bool>> predicate,
TPagedRequest pagedResultRequest,
CancellationToken cancellationToken = default)
{
Container container =
await _containerProvider.GetContainerAsync().ConfigureAwait(false);

IQueryable<TItem> query =
container.GetItemLinqQueryable<TItem>()
.Where(predicate.Compose(
item => !item.Type.IsDefined() || item.Type == typeof(TItem).Name, Expression.AndAlso));

Response<int> response = await query.CountAsync(cancellationToken);
int totalCount = response.Resource;

query = ApplyPaging(query, pagedResultRequest);

TryLogDebugDetails(_logger, () => $"Read: {query}");

using FeedIterator<TItem> iterator = query.ToFeedIterator();
List<TItem> results = new();
while (iterator.HasMoreResults)
{
foreach (TItem result in await iterator.ReadNextAsync(cancellationToken).ConfigureAwait(false))
{
results.Add(result);
}
}
return new PagedResult<TItem>(totalCount, results);
}

protected virtual IQueryable<TItem> ApplyPaging<TPagedRequest>(
IQueryable<TItem> query,
TPagedRequest pagedResultRequest)
{
//Try to use paging if available
if (pagedResultRequest is IPagedResultRequest pagedInput)
{
return query.Skip(pagedInput.SkipCount).Take(pagedInput.MaxResultCount);
}

//Try to limit query result if available
if (pagedResultRequest is ILimitedResultRequest limitedInput)
{
return query.Take(limitedInput.MaxResultCount);
}

//Try to skip if available
if (pagedResultRequest is ISkippedResultRequest skippedInput)
{
return query.Skip(skippedInput.SkipCount);
}

//No paging
return query;
}

/// <inheritdoc/>
public async ValueTask<IEnumerable<TItem>> GetByQueryAsync(
string query,
Expand Down Expand Up @@ -232,4 +292,4 @@ static void TryLogDebugDetails(ILogger logger, Func<string> getMessage)
}
}
}
}
}
16 changes: 15 additions & 1 deletion Microsoft.Azure.CosmosRepository/src/IRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.Cosmos;
using Microsoft.Azure.CosmosRepository.Pagination;


namespace Microsoft.Azure.CosmosRepository
{
Expand Down Expand Up @@ -61,6 +63,18 @@ ValueTask<TItem> GetAsync(
PartitionKey partitionKey,
CancellationToken cancellationToken = default);

/// <summary>
/// Gets an <see cref="PagedResult{TItem}"/> of <see cref="IItem"/>
/// </summary>
/// <param name="predicate">The expression used for evaluating a matching item.</param>
/// <param name="pagedResultRequest">The paging object.</param>
/// <param name="cancellationToken">The cancellation token to use when making asynchronous operations.</param>
/// <returns>A paged result of item instances who meet the <paramref name="predicate"/> and <paramref name="pagedResultRequest"/> condition.</returns>
Task<PagedResult<TItem>> GetListAsync<TPagedRequest>(
Expression<Func<TItem, bool>> predicate,
TPagedRequest pagedResultRequest,
CancellationToken cancellationToken = default);

/// <summary>
/// Gets an <see cref="IEnumerable{TItem}"/> collection of <see cref="IItem"/>
/// implementation classes that match the given <paramref name="predicate"/>.
Expand Down Expand Up @@ -161,4 +175,4 @@ ValueTask DeleteAsync(
PartitionKey partitionKey,
CancellationToken cancellationToken = default);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) IEvangelist. All rights reserved.
// Licensed under the MIT License.

namespace Microsoft.Azure.CosmosRepository.Pagination
{
/// <summary>
/// This interface is defined to standardize to request a limited result.
/// </summary>
public interface ILimitedResultRequest
{
/// <summary>
/// Maximum result count should be returned.
/// This is generally used to limit result count on paging.
/// </summary>
int MaxResultCount { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (c) IEvangelist. All rights reserved.
// Licensed under the MIT License.

namespace Microsoft.Azure.CosmosRepository.Pagination
{
/// <summary>
/// This interface is defined to standardize to request a paged result.
/// </summary>
public interface IPagedResultRequest : ISkippedResultRequest, ILimitedResultRequest
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (c) IEvangelist. All rights reserved.
// Licensed under the MIT License.

namespace Microsoft.Azure.CosmosRepository.Pagination
{
/// <summary>
/// This interface is defined to standardize to request a skipped result.
/// </summary>
public interface ISkippedResultRequest
{
/// <inheritdoc />
int SkipCount { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) IEvangelist. All rights reserved.
// Licensed under the MIT License.

namespace Microsoft.Azure.CosmosRepository.Pagination
{
/// <inheritdoc />
public class LimitedResultRequest : ILimitedResultRequest
{
/// <summary>
/// Default value: 10.
/// </summary>
public static int DefaultMaxResultCount { get; set; } = 10;
zhangzunke marked this conversation as resolved.
Show resolved Hide resolved

/// <inheritdoc />
public int MaxResultCount { get; set; } = DefaultMaxResultCount;
}
}
27 changes: 27 additions & 0 deletions Microsoft.Azure.CosmosRepository/src/Pagination/ListResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) IEvangelist. All rights reserved.
// Licensed under the MIT License.

using System.Collections.Generic;

namespace Microsoft.Azure.CosmosRepository.Pagination
{
/// <summary>
/// List of items
/// </summary>
public class ListResult<T>
{
/// <summary>
/// Creates a new <see cref="ListResult{T}"/> object.
/// </summary>
public ListResult() { }

/// <summary>
/// Creates a new <see cref="ListResult{T}"/> object.
/// </summary>
/// <param name="items">List of items</param>
public ListResult(IReadOnlyList<T> items) => Items = items;

/// <inheritdoc />
public IReadOnlyList<T> Items { get; internal set; } = new List<T>();
}
}
28 changes: 28 additions & 0 deletions Microsoft.Azure.CosmosRepository/src/Pagination/PagedResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) IEvangelist. All rights reserved.
// Licensed under the MIT License.

using System.Collections.Generic;

namespace Microsoft.Azure.CosmosRepository.Pagination
{
/// <inheritdoc />
public class PagedResult<T> : ListResult<T>
{
/// <inheritdoc />
public long TotalCount { get; internal set; }

/// <summary>
/// Creates a new <see cref="PagedResult{T}"/> object.
/// </summary>
public PagedResult() { }

/// <summary>
/// Creates a new <see cref="PagedResult{T}"/> object.
/// </summary>
/// <param name="totalCount">Total count of Items</param>
/// <param name="items">List of items in current page</param>
public PagedResult(long totalCount, IReadOnlyList<T> items)
: base(items) =>
TotalCount = totalCount;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (c) IEvangelist. All rights reserved.
// Licensed under the MIT License.

namespace Microsoft.Azure.CosmosRepository.Pagination
{
/// <inheritdoc />
public class PagedResultRequest : LimitedResultRequest, IPagedResultRequest
{
/// <inheritdoc />
public int SkipCount { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (c) IEvangelist. All rights reserved.
// Licensed under the MIT License.

namespace Microsoft.Azure.CosmosRepository.Pagination
{
/// <inheritdoc />
public class SkippedResultRequest : ISkippedResultRequest
{
/// <inheritdoc />
public int SkipCount { get; set; }
}
}