Update the tutorial for async queryable change.

pull/7388/head
Halil İbrahim Kalkan 4 years ago
parent da59dbcd59
commit de0836b612

@ -364,10 +364,11 @@ namespace Acme.BookStore.Books
public override async Task<BookDto> GetAsync(Guid id) public override async Task<BookDto> GetAsync(Guid id)
{ {
await CheckGetPolicyAsync(); //Get the IQueryable<Book> from the repository
var queryable = await Repository.GetQueryableAsync();
//Prepare a query to join books and authors //Prepare a query to join books and authors
var query = from book in Repository var query = from book in queryable
join author in _authorRepository on book.AuthorId equals author.Id join author in _authorRepository on book.AuthorId equals author.Id
where book.Id == id where book.Id == id
select new { book, author }; select new { book, author };
@ -384,17 +385,18 @@ namespace Acme.BookStore.Books
return bookDto; return bookDto;
} }
public override async Task<PagedResultDto<BookDto>> GetListAsync( public override async Task<PagedResultDto<BookDto>> GetListAsync(PagedAndSortedResultRequestDto input)
PagedAndSortedResultRequestDto input)
{ {
await CheckGetListPolicyAsync(); //Get the IQueryable<Book> from the repository
var queryable = await Repository.GetQueryableAsync();
//Prepare a query to join books and authors //Prepare a query to join books and authors
var query = from book in Repository var query = from book in queryable
join author in _authorRepository on book.AuthorId equals author.Id join author in _authorRepository on book.AuthorId equals author.Id
orderby input.Sorting orderby input.Sorting //TODO: Can not sort like that!
select new {book, author}; select new {book, author};
//Paging
query = query query = query
.Skip(input.SkipCount) .Skip(input.SkipCount)
.Take(input.MaxResultCount); .Take(input.MaxResultCount);
@ -437,7 +439,7 @@ Let's see the changes we've done:
* Injected `IAuthorRepository` to query from the authors. * Injected `IAuthorRepository` to query from the authors.
* Overrode the `GetAsync` method of the base `CrudAppService`, which returns a single `BookDto` object with the given `id`. * Overrode the `GetAsync` method of the base `CrudAppService`, which returns a single `BookDto` object with the given `id`.
* Used a simple LINQ expression to join books and authors and query them together for the given book id. * Used a simple LINQ expression to join books and authors and query them together for the given book id.
* Used `AsyncExecuter.FirstOrDefaultAsync(...)` to execute the query and get a result. `AsyncExecuter` was previously used in the `AuthorAppService`. Check the [repository documentation](../Repositories.md) to understand why we've used it. * Used `AsyncExecuter.FirstOrDefaultAsync(...)` to execute the query and get a result. It is a way to use asynchronous LINQ extensions without depending on the database provider API. Check the [repository documentation](../Repositories.md) to understand why we've used it.
* Throws an `EntityNotFoundException` which results an `HTTP 404` (not found) result if requested book was not present in the database. * Throws an `EntityNotFoundException` which results an `HTTP 404` (not found) result if requested book was not present in the database.
* Finally, created a `BookDto` object using the `ObjectMapper`, then assigning the `AuthorName` manually. * Finally, created a `BookDto` object using the `ObjectMapper`, then assigning the `AuthorName` manually.
* Overrode the `GetListAsync` method of the base `CrudAppService`, which returns a list of books. The logic is similar to the previous method, so you can easily understand the code. * Overrode the `GetListAsync` method of the base `CrudAppService`, which returns a list of books. The logic is similar to the previous method, so you can easily understand the code.
@ -508,10 +510,13 @@ namespace Acme.BookStore.Books
{ {
input.Sorting = nameof(Book.Name); input.Sorting = nameof(Book.Name);
} }
//Get the IQueryable<Book> from the repository
var queryable = await Repository.GetQueryableAsync();
//Get the books //Get the books
var books = await AsyncExecuter.ToListAsync( var books = await AsyncExecuter.ToListAsync(
Repository queryable
.OrderBy(input.Sorting) .OrderBy(input.Sorting)
.Skip(input.SkipCount) .Skip(input.SkipCount)
.Take(input.MaxResultCount) .Take(input.MaxResultCount)
@ -553,8 +558,10 @@ namespace Acme.BookStore.Books
.Distinct() .Distinct()
.ToArray(); .ToArray();
var queryable = await _authorRepository.GetQueryableAsync();
var authors = await AsyncExecuter.ToListAsync( var authors = await AsyncExecuter.ToListAsync(
_authorRepository.Where(a => authorIds.Contains(a.Id)) queryable.Where(a => authorIds.Contains(a.Id))
); );
return authors.ToDictionary(x => x.Id, x => x); return authors.ToDictionary(x => x.Id, x => x);

@ -127,7 +127,8 @@ namespace Acme.BookStore.Authors
public async Task<Author> FindByNameAsync(string name) public async Task<Author> FindByNameAsync(string name)
{ {
return await DbSet.FirstOrDefaultAsync(author => author.Name == name); var dbSet = await GetDbSetAsync();
return await dbSet.FirstOrDefaultAsync(author => author.Name == name);
} }
public async Task<List<Author>> GetListAsync( public async Task<List<Author>> GetListAsync(
@ -136,7 +137,8 @@ namespace Acme.BookStore.Authors
string sorting, string sorting,
string filter = null) string filter = null)
{ {
return await DbSet var dbSet = await GetDbSetAsync();
return await dbSet
.WhereIf( .WhereIf(
!filter.IsNullOrWhiteSpace(), !filter.IsNullOrWhiteSpace(),
author => author.Name.Contains(filter) author => author.Name.Contains(filter)
@ -186,8 +188,8 @@ namespace Acme.BookStore.Authors
public async Task<Author> FindByNameAsync(string name) public async Task<Author> FindByNameAsync(string name)
{ {
return await GetMongoQueryable() var queryable = await GetMongoQueryableAsync();
.FirstOrDefaultAsync(author => author.Name == name); return await queryable.FirstOrDefaultAsync(author => author.Name == name);
} }
public async Task<List<Author>> GetListAsync( public async Task<List<Author>> GetListAsync(
@ -196,7 +198,8 @@ namespace Acme.BookStore.Authors
string sorting, string sorting,
string filter = null) string filter = null)
{ {
return await GetMongoQueryable() var queryable = await GetMongoQueryableAsync();
return await queryable
.WhereIf<Author, IMongoQueryable<Author>>( .WhereIf<Author, IMongoQueryable<Author>>(
!filter.IsNullOrWhiteSpace(), !filter.IsNullOrWhiteSpace(),
author => author.Name.Contains(filter) author => author.Name.Contains(filter)

@ -172,6 +172,7 @@ using System.Threading.Tasks;
using Acme.BookStore.Permissions; using Acme.BookStore.Permissions;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories;
namespace Acme.BookStore.Authors namespace Acme.BookStore.Authors
{ {
@ -230,12 +231,10 @@ public async Task<PagedResultDto<AuthorDto>> GetListAsync(GetAuthorListDto input
input.Filter input.Filter
); );
var totalCount = await AsyncExecuter.CountAsync( var totalCount = input.Filter == null
_authorRepository.WhereIf( ? await _authorRepository.CountAsync()
!input.Filter.IsNullOrWhiteSpace(), : await _authorRepository.CountAsync(
author => author.Name.Contains(input.Filter) author => author.Name.Contains(input.Filter));
)
);
return new PagedResultDto<AuthorDto>( return new PagedResultDto<AuthorDto>(
totalCount, totalCount,
@ -246,7 +245,7 @@ public async Task<PagedResultDto<AuthorDto>> GetListAsync(GetAuthorListDto input
* Default sorting is "by author name" which is done in the beginning of the method in case of it wasn't sent by the client. * Default sorting is "by author name" which is done in the beginning of the method in case of it wasn't sent by the client.
* Used the `IAuthorRepository.GetListAsync` to get a paged, sorted and filtered list of authors from the database. We had implemented it in the previous part of this tutorial. Again, it actually was not needed to create such a method since we could directly query over the repository, but wanted to demonstrate how to create custom repository methods. * Used the `IAuthorRepository.GetListAsync` to get a paged, sorted and filtered list of authors from the database. We had implemented it in the previous part of this tutorial. Again, it actually was not needed to create such a method since we could directly query over the repository, but wanted to demonstrate how to create custom repository methods.
* Directly queried from the `AuthorRepository` while getting the count of the authors. We preferred to use the `AsyncExecuter` service which allows us to perform async queries without depending on the EF Core. However, you could depend on the EF Core package and directly use the `_authorRepository.WhereIf(...).ToListAsync()` method. See the [repository document](../Repositories.md) to read the alternative approaches and the discussion. * Directly queried from the `AuthorRepository` while getting the count of the authors. If a filter is sent, then we are using it to filter entities while getting the count.
* Finally, returning a paged result by mapping the list of `Author`s to a list of `AuthorDto`s. * Finally, returning a paged result by mapping the list of `Author`s to a list of `AuthorDto`s.
### CreateAsync ### CreateAsync

Loading…
Cancel
Save