diff --git a/docs/en/Blog-Posts/2021-01-14 v4_2_Preview/POST.md b/docs/en/Blog-Posts/2021-01-14 v4_2_Preview/POST.md index 0c44e43825..253fc4a803 100644 --- a/docs/en/Blog-Posts/2021-01-14 v4_2_Preview/POST.md +++ b/docs/en/Blog-Posts/2021-01-14 v4_2_Preview/POST.md @@ -32,7 +32,79 @@ See the [ABP CLI documentation](https://docs.abp.io/en/abp/latest/CLI) for all t ## What's new with the ABP Framework 4.2 -TODO +## IRepository.GetQueryableAsync() + +> **This version comes with an important change about using `IQueryable` features over the [repositories](https://docs.abp.io/en/abp/4.2/Repositories). It is suggested to read this section carefully and apply in your applications.** + +`IRepository` interface inherits `IQueryable`, so you can directly use the standard LINQ extension methods, like `Where`, `OrderBy`, `First`, `Sum`... etc. + +**Example: Using LINQ directly over the repository object** + +````csharp +public class BookAppService : ApplicationService, IBookAppService +{ + private readonly IRepository _bookRepository; + + public BookAppService(IRepository bookRepository) + { + _bookRepository = bookRepository; + } + + public async Task DoItInOldWayAsync() + { + //Apply any standard LINQ extension method + var query = _bookRepository + .Where(x => x.Price > 10) + .OrderBy(x => x.Name); + + //Execute the query asynchronously + var books = await AsyncExecuter.ToListAsync(query); + } +} +```` + +*See [the documentation](https://docs.abp.io/en/abp/4.2/Repositories#iqueryable-async-operations) if you wonder what is the `AsyncExecuter`.* + +Beginning from the version 4.2, the recommended way is using `IRepository.GetQueryableAsync()` to obtain an `IQueryable`, then use the LINQ extension methods over it. + +**Example: Using the new GetQueryableAsync method** + +````csharp +public async Task DoItInNewWayAsync() +{ + //Use GetQueryableAsync to obtain the IQueryable first + var queryable = await _bookRepository.GetQueryableAsync(); + + //Then apply any standard LINQ extension method + var query = queryable + .Where(x => x.Price > 10) + .OrderBy(x => x.Name); + + //Finally, execute the query asynchronously + var books = await AsyncExecuter.ToListAsync(query); +} +```` + +ABP may start a database transaction when you get an `IQueryable` (If current [Unit Of Work](https://docs.abp.io/en/abp/latest/Unit-Of-Work) is transactional). In this new way, it is possible to **start the database transaction in an asynchronous way**. Previously, we could not get the advantage of asynchronous while starting the transactions. + +> **The new way has a significant performance and scalability gain. The old usage (directly using LINQ over the repositories) will be removed in the next major version.** You have a lot of time for the change, but we recommend to immediately take the action since the old usage has a big scalability problem. + +#### About IRepository Async Extension Methods + +Using IRepository Async Extension Methods has no such a problem. The examples below are pretty fine: + +````csharp +var countAll = await _personRepository + .CountAsync(); + +var count = await _personRepository + .CountAsync(x => x.Name.StartsWith("A")); + +var book1984 = await _bookRepository + .FirstOrDefaultAsync(x => x.Name == "John"); +```` + +See the [repository documentation](https://docs.abp.io/en/abp/4.2/Repositories#iqueryable-async-operations) to understand the relation between `IQueryable` and asynchronous operations. ## What's new with the ABP Commercial 4.2