Browse Source

Merge pull request #7410 from abpframework/auto-merge/rel-4-2/126

Merge branch dev with rel-4.2
pull/7420/head
liangshiwei 6 years ago
committed by GitHub
parent
commit
a9a990bed8
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      docs/en/Dependency-Injection.md
  2. 101
      docs/en/Migration-Guides/Abp-4_2.md
  3. 5
      docs/en/Migration-Guides/Index.md
  4. 1
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/MyCompanyName.MyProjectName.Blazor.csproj
  5. 1
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations.csproj
  6. 8
      templates/app/aspnet-core/src/MyCompanyName.MyProjectName.MongoDB/MongoDb/MongoDbMyProjectNameDbSchemaMigrator.cs
  7. 2
      templates/app/aspnet-core/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/EntityFrameworkCore/Samples/SampleRepositoryTests.cs
  8. 3
      templates/app/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDb/Samples/SampleRepositoryTests.cs

2
docs/en/Dependency-Injection.md

@ -1,6 +1,6 @@
# Dependency Injection
ABP's Dependency Injection system is developed based on Microsoft's [dependency injection extension](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection) library (Microsoft.Extensions.DependencyInjection nuget package). So, it's documentation is valid in ABP too.
ABP's Dependency Injection system is developed based on Microsoft's [dependency injection extension](https://medium.com/volosoft/asp-net-core-dependency-injection-best-practices-tips-tricks-c6e9c67f9d96) library (Microsoft.Extensions.DependencyInjection nuget package). So, it's documentation is valid in ABP too.
> While ABP has no core dependency to any 3rd-party DI provider, it's required to use a provider that supports dynamic proxying and some other advanced features to make some ABP features properly work. Startup templates come with Autofac installed. See [Autofac integration](Autofac-Integration.md) document for more information.

101
docs/en/Migration-Guides/Abp-4_2.md

@ -0,0 +1,101 @@
# ABP version 4.2 Migration Guide
This version has no breaking changes but there is an important change on the repositories that should be applied for your application for an important performance and scalability gain.
## IRepository.GetQueryableAsync
`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<Book, Guid> _bookRepository;
public BookAppService(IRepository<Book, Guid> 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<Book> 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 (5.0).** 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**.
### Actions to Take
* Use the repository's queryable feature as explained before.
* If you've overridden `CreateFilteredQuery` in a class derived from `CrudAppService`, you should override the `CreateFilteredQueryAsync` instead and remove the `CreateFilteredQuery` in your class.
* If you've overridden `WithDetails` in your custom repositories, remove it and override `WithDetailsAsync` instead.
* If you've used `DbContext` or `DbSet` properties in your custom repositories, use `GetDbContextAsync()` and `GetDbSetAsync()` methods instead of them.
You can re-build your solution and check the `Obsolete` warnings to find some of the usages need to change.
#### 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.
## .NET Package Upgrades
ABP uses the latest 5.0.* .NET packages. If your application is using 5.0.0 packages, you may get an error on build. We recommend to depend on the .NET packages like `5.0.*` in the `.csproj` files to use the latest patch versions.
Example:
````xml
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.*" />
````
## Blazorise Library Upgrade
If you are upgrading to 4.2, you also need also upgrade the following packages in your Blazor application;
* `Blazorise.Bootstrap` to `0.9.3-preview6`
* `Blazorise.Icons.FontAwesome` to `0.9.3-preview6`

5
docs/en/Migration-Guides/Index.md

@ -1,5 +1,6 @@
# ABP Framework Migration Guides
* [3.3.x to 4.0 Migration Guide](Abp-4_0.md)
* [2.9.x to 3.0 Migration Guide](../UI/Angular/Migration-Guide-v3.md)
* [4.x to 4.2](Abp-4_2.md)
* [3.3.x to 4.0](Abp-4_0.md)
* [2.9.x to 3.0](../UI/Angular/Migration-Guide-v3.md)

1
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor/MyCompanyName.MyProjectName.Blazor.csproj

@ -4,6 +4,7 @@
<TargetFramework>net5.0</TargetFramework>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
<BlazorWebAssemblyEnableLinking>false</BlazorWebAssemblyEnableLinking>
<PublishTrimmed>false</PublishTrimmed>
</PropertyGroup>
<ItemGroup>

1
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations.csproj

@ -12,6 +12,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.*" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.*" />
</ItemGroup>

8
templates/app/aspnet-core/src/MyCompanyName.MyProjectName.MongoDB/MongoDb/MongoDbMyProjectNameDbSchemaMigrator.cs

@ -18,15 +18,15 @@ namespace MyCompanyName.MyProjectName.MongoDB
_serviceProvider = serviceProvider;
}
public Task MigrateAsync()
public async Task MigrateAsync()
{
var dbContexts = _serviceProvider.GetServices<IAbpMongoDbContext>();
var connectionStringResolver = _serviceProvider.GetService<IConnectionStringResolver>();
var connectionStringResolver = _serviceProvider.GetRequiredService<IConnectionStringResolver>();
foreach (var dbContext in dbContexts)
{
var connectionString =
connectionStringResolver.Resolve(
await connectionStringResolver.ResolveAsync(
ConnectionStringNameAttribute.GetConnStringName(dbContext.GetType()));
var mongoUrl = new MongoUrl(connectionString);
var databaseName = mongoUrl.DatabaseName;
@ -39,8 +39,6 @@ namespace MyCompanyName.MyProjectName.MongoDB
(dbContext as AbpMongoDbContext)?.InitializeCollections(client.GetDatabase(databaseName));
}
return Task.CompletedTask;
}
}
}

2
templates/app/aspnet-core/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/EntityFrameworkCore/Samples/SampleRepositoryTests.cs

@ -33,7 +33,7 @@ namespace MyCompanyName.MyProjectName.EntityFrameworkCore.Samples
await WithUnitOfWorkAsync(async () =>
{
//Act
var adminUser = await _appUserRepository
var adminUser = await (await _appUserRepository.GetQueryableAsync())
.Where(u => u.UserName == "admin")
.FirstOrDefaultAsync();

3
templates/app/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MongoDb/Samples/SampleRepositoryTests.cs

@ -32,8 +32,7 @@ namespace MyCompanyName.MyProjectName.MongoDB.Samples
await WithUnitOfWorkAsync(async () =>
{
//Act
var adminUser = await _appUserRepository
.GetMongoQueryable()
var adminUser = await (await _appUserRepository.GetMongoQueryableAsync())
.FirstOrDefaultAsync(u => u.UserName == "admin");
//Assert

Loading…
Cancel
Save