Browse Source

Merge pull request #6809 from abpframework/async-uow-transaction

Transaction management made async
pull/6978/head
maliming 6 years ago
committed by GitHub
parent
commit
4185454046
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Pagination/PagerModel.cs
  2. 2
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowActionFilter.cs
  3. 2
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowPageFilter.cs
  4. 4
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpUnitOfWorkMiddleware.cs
  5. 52
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AspNetCoreUnitOfWorkTransactionBehaviourProvider.cs
  6. 17
      framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AspNetCoreUnitOfWorkTransactionBehaviourProviderOptions.cs
  7. 6
      framework/src/Volo.Abp.Authorization/Microsoft/AspNetCore/Authorization/AuthorizationOptionsExtensions.cs
  8. 16
      framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs
  9. 10
      framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionGroupDefinition.cs
  10. 4
      framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IAsyncBackgroundJob.cs
  11. 4
      framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IBackgroundJob.cs
  12. 4
      framework/src/Volo.Abp.BlazoriseUI/AbpCrudPageBase.cs
  13. 3
      framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainerFactoryExtensions.cs
  14. 2
      framework/src/Volo.Abp.Core/System/AbpStringExtensions.cs
  15. 2
      framework/src/Volo.Abp.Core/System/Collections/Generic/AbpCollectionExtensions.cs
  16. 4
      framework/src/Volo.Abp.Core/Volo/Abp/Reflection/TypeFinder.cs
  17. 6
      framework/src/Volo.Abp.Core/Volo/Abp/Text/Formatting/FormattedStringValueExtracter.cs
  18. 12
      framework/src/Volo.Abp.Dapper/Volo/Abp/Domain/Repositories/Dapper/DapperRepository.cs
  19. 12
      framework/src/Volo.Abp.Dapper/Volo/Abp/Domain/Repositories/Dapper/IDapperRepository.cs
  20. 6
      framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeedContext.cs
  21. 16
      framework/src/Volo.Abp.Data/Volo/Abp/Data/DefaultConnectionStringResolver.cs
  22. 8
      framework/src/Volo.Abp.Data/Volo/Abp/Data/IConnectionStringResolver.cs
  23. 14
      framework/src/Volo.Abp.Data/Volo/Abp/Data/IConnectionStringResolverExtensions.cs
  24. 10
      framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyCrudAppService.cs
  25. 36
      framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyReadOnlyAppService.cs
  26. 4
      framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/CrudAppService.cs
  27. 4
      framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ReadOnlyAppService.cs
  28. 6
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/IAbpCommonDbContextRegistrationOptionsBuilder.cs
  29. 9
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IReadOnlyRepository.cs
  30. 22
      framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryBase.cs
  31. 15
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EfCoreRepositoryExtensions.cs
  32. 178
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs
  33. 10
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/IEfCoreRepository.cs
  34. 4
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/DbContextOptionsFactory.cs
  35. 2
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/EfCoreAsyncQueryableProvider.cs
  36. 10
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/IDbContextProvider.cs
  37. 2
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/ObjectExtending/EfCoreObjectExtensionManagerExtensions.cs
  38. 132
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/UnitOfWorkDbContextProvider.cs
  39. 4
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventBus.cs
  40. 4
      framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventDataMayHaveTenantId.cs
  41. 4
      framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureDefinition.cs
  42. 8
      framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureGroupDefinition.cs
  43. 9
      framework/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/IMemoryDbRepository.cs
  44. 77
      framework/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDbRepository.cs
  45. 17
      framework/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDbCoreRepositoryExtensions.cs
  46. 12
      framework/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/IMemoryDatabaseProvider.cs
  47. 36
      framework/src/Volo.Abp.MemoryDb/Volo/Abp/Uow/MemoryDb/UnitOfWorkMemoryDatabaseProvider.cs
  48. 14
      framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/IMongoDbRepository.cs
  49. 253
      framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs
  50. 24
      framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDbCoreRepositoryExtensions.cs
  51. 13
      framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/IMongoDbContextProvider.cs
  52. 2
      framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/MongoDbAsyncQueryableProvider.cs
  53. 133
      framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs
  54. 4
      framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ITenantStore.cs
  55. 53
      framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/MultiTenantConnectionStringResolver.cs
  56. 2
      framework/src/Volo.Abp.Threading/Volo/Abp/Linq/AsyncQueryableExecuter.cs
  57. 7
      framework/src/Volo.Abp.Uow/Volo/Abp/Uow/IUnitOfWorkTransactionBehaviourProvider.cs
  58. 9
      framework/src/Volo.Abp.Uow/Volo/Abp/Uow/NullUnitOfWorkTransactionBehaviourProvider.cs
  59. 4
      framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWork.cs
  60. 4
      framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkFailedEventArgs.cs
  61. 23
      framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkInterceptor.cs
  62. 6
      framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/Auditing_Tests.cs
  63. 4
      framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AbpAutoMapperModule_Basic_Tests.cs
  64. 15
      framework/test/Volo.Abp.Dapper.Tests/Volo/Abp/Dapper/Repositories/PersonDapperRepository.cs
  65. 15
      framework/test/Volo.Abp.Data.Tests/Volo/Abp/Data/ConnectionStringResolver_Tests.cs
  66. 6
      framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Repositories/RepositoryRegistration_Tests.cs
  67. 8
      framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/DbContext_Replace_Tests.cs
  68. 6
      framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Domain/ExtraProperties_Tests.cs
  69. 4
      framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/CityRepository.cs
  70. 4
      framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/PersonRepository.cs
  71. 8
      framework/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/TestApp/MemoryDb/CityRepository.cs
  72. 4
      framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/MongoDbAsyncQueryableProvider_Tests.cs
  73. 4
      framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/TestApp/MongoDb/CityRepository.cs
  74. 21
      framework/test/Volo.Abp.MultiTenancy.Tests/Volo/Abp/Data/MultiTenancy/MultiTenantConnectionStringResolver_Tests.cs
  75. 10
      framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/Repository_Queryable_Tests.cs
  76. 34
      framework/test/Volo.Abp.Uow.Tests/Volo/Abp/Uow/UnitOfWork_Events_Tests.cs
  77. 52
      modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs
  78. 25
      modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs
  79. 9
      modules/background-jobs/src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo/Abp/BackgroundJobs/EntityFrameworkCore/EfCoreBackgroundJobRepository.cs
  80. 11
      modules/background-jobs/src/Volo.Abp.BackgroundJobs.MongoDB/Volo/Abp/BackgroundJobs/MongoDB/MongoBackgroundJobRepository.cs
  81. 7
      modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.EntityFrameworkCore/Volo/Abp/BlobStoring/Database/EntityFrameworkCore/EfCoreDatabaseBlobContainerRepository.cs
  82. 13
      modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.EntityFrameworkCore/Volo/Abp/BlobStoring/Database/EntityFrameworkCore/EfCoreDatabaseBlobRepository.cs
  83. 30
      modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.MongoDB/Volo/Abp/BlobStoring/Database/MongoDB/MongoDbDatabaseBlobRepository.cs
  84. 6
      modules/feature-management/src/Volo.Abp.FeatureManagement.EntityFrameworkCore/Volo/Abp/FeatureManagement/EntityFrameworkCore/EfCoreFeatureValueRepository.cs
  85. 6
      modules/feature-management/src/Volo.Abp.FeatureManagement.MongoDB/Volo/Abp/FeatureManagement/MongoDB/MongoFeatureValueRepository.cs
  86. 5
      modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/OrganizationUnit.cs
  87. 29
      modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EFCoreIdentitySecurityLogRepository.cs
  88. 8
      modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityClaimTypeRepository.cs
  89. 6
      modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityLinkUserRepository.cs
  90. 19
      modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs
  91. 93
      modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityUserRepository.cs
  92. 66
      modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreOrganizationUnitRepository.cs
  93. 8
      modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityClaimTypeRepository.cs
  94. 4
      modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityLinkUserRepository.cs
  95. 12
      modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs
  96. 10
      modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentitySecurityLogRepository.cs
  97. 65
      modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityUserRepository.cs
  98. 62
      modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoOrganizationUnitRepository.cs
  99. 34
      modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/ApiResources/ApiResourceRepository.cs
  100. 25
      modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/ApiScopes/ApiScopeRepository.cs

2
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Pagination/PagerModel.cs

@ -69,7 +69,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Pagination
}
/// <summary>
/// Gets first two, previous & current & next, last two pages
/// Gets first two, previous, current, next, last two pages
/// </summary>
private List<PageItem> GetPagesWithGaps()
{

2
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowActionFilter.cs

@ -46,7 +46,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Uow
var options = CreateOptions(context, unitOfWorkAttr);
//Trying to begin a reserved UOW by AbpUnitOfWorkMiddleware
if (_unitOfWorkManager.TryBeginReserved(AbpUnitOfWorkMiddleware.UnitOfWorkReservationName, options))
if (_unitOfWorkManager.TryBeginReserved(UnitOfWork.UnitOfWorkReservationName, options))
{
var result = await next();
if (!Succeed(result))

2
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowPageFilter.cs

@ -50,7 +50,7 @@ namespace Volo.Abp.AspNetCore.Mvc.Uow
var options = CreateOptions(context, unitOfWorkAttr);
//Trying to begin a reserved UOW by AbpUnitOfWorkMiddleware
if (_unitOfWorkManager.TryBeginReserved(AbpUnitOfWorkMiddleware.UnitOfWorkReservationName, options))
if (_unitOfWorkManager.TryBeginReserved(UnitOfWork.UnitOfWorkReservationName, options))
{
var result = await next();
if (!Succeed(result))

4
framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpUnitOfWorkMiddleware.cs

@ -7,8 +7,6 @@ namespace Volo.Abp.AspNetCore.Uow
{
public class AbpUnitOfWorkMiddleware : IMiddleware, ITransientDependency
{
public const string UnitOfWorkReservationName = "_AbpActionUnitOfWork";
private readonly IUnitOfWorkManager _unitOfWorkManager;
public AbpUnitOfWorkMiddleware(IUnitOfWorkManager unitOfWorkManager)
@ -18,7 +16,7 @@ namespace Volo.Abp.AspNetCore.Uow
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
using (var uow = _unitOfWorkManager.Reserve(UnitOfWorkReservationName))
using (var uow = _unitOfWorkManager.Reserve(UnitOfWork.UnitOfWorkReservationName))
{
await next(context);
await uow.CompleteAsync(context.RequestAborted);

52
framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AspNetCoreUnitOfWorkTransactionBehaviourProvider.cs

@ -0,0 +1,52 @@
using System;
using System.Net.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Uow;
namespace Volo.Abp.AspNetCore.Uow
{
public class AspNetCoreUnitOfWorkTransactionBehaviourProvider : IUnitOfWorkTransactionBehaviourProvider, ISingletonDependency
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly AspNetCoreUnitOfWorkTransactionBehaviourProviderOptions _options;
public virtual bool? IsTransactional
{
get
{
var httpContext = _httpContextAccessor.HttpContext;
if (httpContext == null)
{
return null;
}
var currentUrl = httpContext.Request.Path.Value;
if (currentUrl != null)
{
foreach (var url in _options.NonTransactionalUrls)
{
if (currentUrl.StartsWith(url, StringComparison.OrdinalIgnoreCase))
{
return false;
}
}
}
return !string.Equals(
httpContext.Request.Method,
HttpMethod.Get.Method, StringComparison.OrdinalIgnoreCase
);
}
}
public AspNetCoreUnitOfWorkTransactionBehaviourProvider(
IHttpContextAccessor httpContextAccessor,
IOptions<AspNetCoreUnitOfWorkTransactionBehaviourProviderOptions> options)
{
_httpContextAccessor = httpContextAccessor;
_options = options.Value;
}
}
}

17
framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AspNetCoreUnitOfWorkTransactionBehaviourProviderOptions.cs

@ -0,0 +1,17 @@
using System.Collections.Generic;
namespace Volo.Abp.AspNetCore.Uow
{
public class AspNetCoreUnitOfWorkTransactionBehaviourProviderOptions
{
public List<string> NonTransactionalUrls { get; }
public AspNetCoreUnitOfWorkTransactionBehaviourProviderOptions()
{
NonTransactionalUrls = new List<string>
{
"/connect/"
};
}
}
}

6
framework/src/Volo.Abp.Authorization/Microsoft/AspNetCore/Authorization/AuthorizationOptionsExtensions.cs

@ -11,9 +11,9 @@ namespace Microsoft.AspNetCore.Authorization
/// <summary>
/// Gets all policies.
///
///
/// IMPORTANT NOTE: Use this method carefully.
/// It relies on reflection to get all policies from a private field of the <see cref="options"/>.
/// It relies on reflection to get all policies from a private field of the <paramref name="options"/>.
/// This method may be removed in the future if internals of <see cref="AuthorizationOptions"/> changes.
/// </summary>
/// <param name="options"></param>
@ -23,4 +23,4 @@ namespace Microsoft.AspNetCore.Authorization
return ((IDictionary<string, AuthorizationPolicy>) PolicyMapProperty.GetValue(options)).Keys.ToList();
}
}
}
}

16
framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs

@ -54,7 +54,7 @@ namespace Volo.Abp.Authorization.Permissions
///
/// Disabling a permission would be helpful to hide a related application
/// functionality from users/clients.
///
///
/// Default: true.
/// </summary>
public bool IsEnabled { get; set; }
@ -64,8 +64,8 @@ namespace Volo.Abp.Authorization.Permissions
/// </summary>
/// <param name="name">Name of the property</param>
/// <returns>
/// Returns the value in the <see cref="Properties"/> dictionary by given <see cref="name"/>.
/// Returns null if given <see cref="name"/> is not present in the <see cref="Properties"/> dictionary.
/// Returns the value in the <see cref="Properties"/> dictionary by given <paramref name="name"/>.
/// Returns null if given <paramref name="name"/> is not present in the <see cref="Properties"/> dictionary.
/// </returns>
public object this[string name]
{
@ -74,7 +74,7 @@ namespace Volo.Abp.Authorization.Permissions
}
protected internal PermissionDefinition(
[NotNull] string name,
[NotNull] string name,
ILocalizableString displayName = null,
MultiTenancySides multiTenancySide = MultiTenancySides.Both,
bool isEnabled = true)
@ -90,14 +90,14 @@ namespace Volo.Abp.Authorization.Permissions
}
public virtual PermissionDefinition AddChild(
[NotNull] string name,
[NotNull] string name,
ILocalizableString displayName = null,
MultiTenancySides multiTenancySide = MultiTenancySides.Both,
bool isEnabled = true)
{
var child = new PermissionDefinition(
name,
displayName,
name,
displayName,
multiTenancySide,
isEnabled)
{
@ -138,4 +138,4 @@ namespace Volo.Abp.Authorization.Permissions
return $"[{nameof(PermissionDefinition)} {Name}]";
}
}
}
}

10
framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionGroupDefinition.cs

@ -36,8 +36,8 @@ namespace Volo.Abp.Authorization.Permissions
/// </summary>
/// <param name="name">Name of the property</param>
/// <returns>
/// Returns the value in the <see cref="Properties"/> dictionary by given <see cref="name"/>.
/// Returns null if given <see cref="name"/> is not present in the <see cref="Properties"/> dictionary.
/// Returns the value in the <see cref="Properties"/> dictionary by given <paramref name="name"/>.
/// Returns null if given <paramref name="name"/> is not present in the <see cref="Properties"/> dictionary.
/// </returns>
public object this[string name]
{
@ -46,7 +46,7 @@ namespace Volo.Abp.Authorization.Permissions
}
protected internal PermissionGroupDefinition(
string name,
string name,
ILocalizableString displayName = null,
MultiTenancySides multiTenancySide = MultiTenancySides.Both)
{
@ -59,7 +59,7 @@ namespace Volo.Abp.Authorization.Permissions
}
public virtual PermissionDefinition AddPermission(
string name,
string name,
ILocalizableString displayName = null,
MultiTenancySides multiTenancySide = MultiTenancySides.Both,
bool isEnabled = true)
@ -131,4 +131,4 @@ namespace Volo.Abp.Authorization.Permissions
return null;
}
}
}
}

4
framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IAsyncBackgroundJob.cs

@ -8,9 +8,9 @@ namespace Volo.Abp.BackgroundJobs
public interface IAsyncBackgroundJob<in TArgs>
{
/// <summary>
/// Executes the job with the <see cref="args"/>.
/// Executes the job with the <paramref name="args"/>.
/// </summary>
/// <param name="args">Job arguments.</param>
Task ExecuteAsync(TArgs args);
}
}
}

4
framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IBackgroundJob.cs

@ -6,9 +6,9 @@
public interface IBackgroundJob<in TArgs>
{
/// <summary>
/// Executes the job with the <see cref="args"/>.
/// Executes the job with the <paramref name="args"/>.
/// </summary>
/// <param name="args">Job arguments.</param>
void Execute(TArgs args);
}
}
}

4
framework/src/Volo.Abp.BlazoriseUI/AbpCrudPageBase.cs

@ -439,10 +439,10 @@ namespace Volo.Abp.BlazoriseUI
}
/// <summary>
/// Calls IAuthorizationService.CheckAsync for the given <see cref="policyName"/>.
/// Calls IAuthorizationService.CheckAsync for the given <paramref name="policyName"/>.
/// Throws <see cref="AbpAuthorizationException"/> if given policy was not granted for the current user.
///
/// Does nothing if <see cref="policyName"/> is null or empty.
/// Does nothing if <paramref name="policyName"/> is null or empty.
/// </summary>
/// <param name="policyName">A policy name to check</param>
protected virtual async Task CheckPolicyAsync([CanBeNull] string policyName)

3
framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainerFactoryExtensions.cs

@ -6,7 +6,6 @@
/// Gets a named container.
/// </summary>
/// <param name="blobContainerFactory">The blob container manager</param>
/// <param name="cancellationToken">Cancellation token</param>
/// <returns>
/// The container object.
/// </returns>
@ -19,4 +18,4 @@
);
}
}
}
}

2
framework/src/Volo.Abp.Core/System/AbpStringExtensions.cs

@ -88,7 +88,7 @@ namespace System
/// Gets index of nth occurrence of a char in a string.
/// </summary>
/// <param name="str">source string to be searched</param>
/// <param name="c">Char to search in <see cref="str"/></param>
/// <param name="c">Char to search in <paramref name="str"/></param>
/// <param name="n">Count of the occurrence</param>
public static int NthIndexOf(this string str, char c, int n)
{

2
framework/src/Volo.Abp.Core/System/Collections/Generic/AbpCollectionExtensions.cs

@ -107,7 +107,7 @@ namespace System.Collections.Generic
}
/// <summary>
/// Removes all items from the collection those satisfy the given <paramref name="predicate"/>.
/// Removes all items from the collection.
/// </summary>
/// <typeparam name="T">Type of the items in the collection</typeparam>
/// <param name="source">The collection</param>

4
framework/src/Volo.Abp.Core/Volo/Abp/Reflection/TypeFinder.cs

@ -37,7 +37,7 @@ namespace Volo.Abp.Reflection
allTypes.AddRange(typesInThisAssembly.Where(type => type != null));
}
catch (Exception ex)
catch
{
//TODO: Trigger a global event?
}
@ -46,4 +46,4 @@ namespace Volo.Abp.Reflection
return allTypes;
}
}
}
}

6
framework/src/Volo.Abp.Core/Volo/Abp/Text/Formatting/FormattedStringValueExtracter.cs

@ -11,7 +11,7 @@ namespace Volo.Abp.Text.Formatting
/// </summary>
/// <example>
/// Say that str is "My name is Neo." and format is "My name is {name}.".
/// Then Extract method gets "Neo" as "name".
/// Then Extract method gets "Neo" as "name".
/// </example>
public class FormattedStringValueExtracter
{
@ -84,7 +84,7 @@ namespace Volo.Abp.Text.Formatting
}
/// <summary>
/// Checks if given <see cref="str"/> fits to given <see cref="format"/>.
/// Checks if given <paramref name="str"/> fits to given <paramref name="format"/>.
/// Also gets extracted values.
/// </summary>
/// <param name="str">String including dynamic values</param>
@ -127,4 +127,4 @@ namespace Volo.Abp.Text.Formatting
}
}
}
}
}

12
framework/src/Volo.Abp.Dapper/Volo/Abp/Domain/Repositories/Dapper/DapperRepository.cs

@ -1,4 +1,6 @@
using System.Data;
using System;
using System.Data;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using Volo.Abp.EntityFrameworkCore;
@ -16,8 +18,14 @@ namespace Volo.Abp.Domain.Repositories.Dapper
_dbContextProvider = dbContextProvider;
}
[Obsolete("Use GetDbConnectionAsync method.")]
public IDbConnection DbConnection => _dbContextProvider.GetDbContext().Database.GetDbConnection();
public async Task<IDbConnection> GetDbConnectionAsync() => (await _dbContextProvider.GetDbContextAsync()).Database.GetDbConnection();
[Obsolete("Use GetDbTransactionAsync method.")]
public IDbTransaction DbTransaction => _dbContextProvider.GetDbContext().Database.CurrentTransaction?.GetDbTransaction();
public async Task<IDbTransaction> GetDbTransactionAsync() => (await _dbContextProvider.GetDbContextAsync()).Database.CurrentTransaction?.GetDbTransaction();
}
}
}

12
framework/src/Volo.Abp.Dapper/Volo/Abp/Domain/Repositories/Dapper/IDapperRepository.cs

@ -1,11 +1,19 @@
using System.Data;
using System;
using System.Data;
using System.Threading.Tasks;
namespace Volo.Abp.Domain.Repositories.Dapper
{
public interface IDapperRepository
{
[Obsolete("Use GetDbConnectionAsync method.")]
IDbConnection DbConnection { get; }
Task<IDbConnection> GetDbConnectionAsync();
[Obsolete("Use GetDbTransactionAsync method.")]
IDbTransaction DbTransaction { get; }
Task<IDbTransaction> GetDbTransactionAsync();
}
}
}

6
framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeedContext.cs

@ -13,8 +13,8 @@ namespace Volo.Abp.Data
/// </summary>
/// <param name="name">Name of the property</param>
/// <returns>
/// Returns the value in the <see cref="Properties"/> dictionary by given <see cref="name"/>.
/// Returns null if given <see cref="name"/> is not present in the <see cref="Properties"/> dictionary.
/// Returns the value in the <see cref="Properties"/> dictionary by given <paramref name="name"/>.
/// Returns null if given <paramref name="name"/> is not present in the <see cref="Properties"/> dictionary.
/// </returns>
[CanBeNull]
public object this[string name]
@ -45,4 +45,4 @@ namespace Volo.Abp.Data
return this;
}
}
}
}

16
framework/src/Volo.Abp.Data/Volo/Abp/Data/DefaultConnectionStringResolver.cs

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
@ -14,7 +15,18 @@ namespace Volo.Abp.Data
Options = options.Value;
}
[Obsolete("Use ResolveAsync method.")]
public virtual string Resolve(string connectionStringName = null)
{
return ResolveInternal(connectionStringName);
}
public virtual Task<string> ResolveAsync(string connectionStringName = null)
{
return Task.FromResult(ResolveInternal(connectionStringName));
}
private string ResolveInternal(string connectionStringName)
{
//Get module specific value if provided
if (!connectionStringName.IsNullOrEmpty())
@ -25,9 +37,9 @@ namespace Volo.Abp.Data
return moduleConnString;
}
}
//Get default value
return Options.ConnectionStrings.Default;
}
}
}
}

8
framework/src/Volo.Abp.Data/Volo/Abp/Data/IConnectionStringResolver.cs

@ -1,10 +1,16 @@
using JetBrains.Annotations;
using System;
using System.Threading.Tasks;
using JetBrains.Annotations;
namespace Volo.Abp.Data
{
public interface IConnectionStringResolver
{
[NotNull]
[Obsolete("Use ResolveAsync method.")]
string Resolve(string connectionStringName = null);
[NotNull]
Task<string> ResolveAsync(string connectionStringName = null);
}
}

14
framework/src/Volo.Abp.Data/Volo/Abp/Data/IConnectionStringResolverExtensions.cs

@ -1,10 +1,22 @@
namespace Volo.Abp.Data
using System;
using System.Threading.Tasks;
using JetBrains.Annotations;
namespace Volo.Abp.Data
{
public static class ConnectionStringResolverExtensions
{
[NotNull]
[Obsolete("Use ResolveAsync method")]
public static string Resolve<T>(this IConnectionStringResolver resolver)
{
return resolver.Resolve(ConnectionStringNameAttribute.GetConnStringName<T>());
}
[NotNull]
public static Task<string> ResolveAsync<T>(this IConnectionStringResolver resolver)
{
return resolver.ResolveAsync(ConnectionStringNameAttribute.GetConnStringName<T>());
}
}
}

10
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyCrudAppService.cs

@ -132,7 +132,7 @@ namespace Volo.Abp.Application.Services
}
/// <summary>
/// Maps <see cref="TCreateInput"/> to <see cref="TEntity"/> to create a new entity.
/// Maps <typeparamref name="TCreateInput"/> to <typeparamref name="TEntity"/> to create a new entity.
/// It uses <see cref="MapToEntity(TCreateInput)"/> by default.
/// It can be overriden for custom mapping.
/// Overriding this has higher priority than overriding the <see cref="MapToEntity(TCreateInput)"/>
@ -143,7 +143,7 @@ namespace Volo.Abp.Application.Services
}
/// <summary>
/// Maps <see cref="TCreateInput"/> to <see cref="TEntity"/> to create a new entity.
/// Maps <typeparamref name="TCreateInput"/> to <typeparamref name="TEntity"/> to create a new entity.
/// It uses <see cref="IObjectMapper"/> by default.
/// It can be overriden for custom mapping.
/// </summary>
@ -155,7 +155,7 @@ namespace Volo.Abp.Application.Services
}
/// <summary>
/// Sets Id value for the entity if <see cref="TKey"/> is <see cref="Guid"/>.
/// Sets Id value for the entity if <typeparamref name="TKey"/> is <see cref="Guid"/>.
/// It's used while creating a new entity.
/// </summary>
protected virtual void SetIdForGuids(TEntity entity)
@ -171,7 +171,7 @@ namespace Volo.Abp.Application.Services
}
/// <summary>
/// Maps <see cref="TUpdateInput"/> to <see cref="TEntity"/> to update the entity.
/// Maps <typeparamref name="TUpdateInput"/> to <typeparamref name="TEntity"/> to update the entity.
/// It uses <see cref="MapToEntity(TUpdateInput, TEntity)"/> by default.
/// It can be overriden for custom mapping.
/// Overriding this has higher priority than overriding the <see cref="MapToEntity(TUpdateInput, TEntity)"/>
@ -183,7 +183,7 @@ namespace Volo.Abp.Application.Services
}
/// <summary>
/// Maps <see cref="TUpdateInput"/> to <see cref="TEntity"/> to update the entity.
/// Maps <typeparamref name="TUpdateInput"/> to <typeparamref name="TEntity"/> to update the entity.
/// It uses <see cref="IObjectMapper"/> by default.
/// It can be overriden for custom mapping.
/// </summary>

36
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyReadOnlyAppService.cs

@ -62,7 +62,7 @@ namespace Volo.Abp.Application.Services
{
await CheckGetListPolicyAsync();
var query = CreateFilteredQuery(input);
var query = await CreateFilteredQueryAsync(input);
var totalCount = await AsyncExecuter.CountAsync(query);
@ -160,13 +160,37 @@ namespace Volo.Abp.Application.Services
/// methods.
/// </summary>
/// <param name="input">The input.</param>
[Obsolete("Override the CreateFilteredQueryAsync method instead.")]
protected virtual IQueryable<TEntity> CreateFilteredQuery(TGetListInput input)
{
return ReadOnlyRepository;
}
/// <summary>
/// Maps <see cref="TEntity"/> to <see cref="TGetOutputDto"/>.
/// This method should create <see cref="IQueryable{TEntity}"/> based on given input.
/// It should filter query if needed, but should not do sorting or paging.
/// Sorting should be done in <see cref="ApplySorting"/> and paging should be done in <see cref="ApplyPaging"/>
/// methods.
/// </summary>
/// <param name="input">The input.</param>
protected virtual async Task<IQueryable<TEntity>> CreateFilteredQueryAsync(TGetListInput input)
{
/* If user has overridden the CreateFilteredQuery method,
* we don't want to make breaking change in this point.
*/
#pragma warning disable 618
var query = CreateFilteredQuery(input);
#pragma warning restore 618
if (!ReferenceEquals(query, ReadOnlyRepository))
{
return query;
}
return await ReadOnlyRepository.GetQueryableAsync();
}
/// <summary>
/// Maps <typeparamref name="TEntity"/> to <typeparamref name="TGetOutputDto"/>.
/// It internally calls the <see cref="MapToGetOutputDto"/> by default.
/// It can be overriden for custom mapping.
/// Overriding this has higher priority than overriding the <see cref="MapToGetOutputDto"/>
@ -177,7 +201,7 @@ namespace Volo.Abp.Application.Services
}
/// <summary>
/// Maps <see cref="TEntity"/> to <see cref="TGetOutputDto"/>.
/// Maps <typeparamref name="TEntity"/> to <typeparamref name="TGetOutputDto"/>.
/// It uses <see cref="IObjectMapper"/> by default.
/// It can be overriden for custom mapping.
/// </summary>
@ -187,7 +211,7 @@ namespace Volo.Abp.Application.Services
}
/// <summary>
/// Maps a list of <see cref="TEntity"/> to <see cref="TGetListOutputDto"/> objects.
/// Maps a list of <typeparamref name="TEntity"/> to <typeparamref name="TGetListOutputDto"/> objects.
/// It uses <see cref="MapToGetListOutputDtoAsync"/> method for each item in the list.
/// </summary>
protected virtual async Task<List<TGetListOutputDto>> MapToGetListOutputDtosAsync(List<TEntity> entities)
@ -203,7 +227,7 @@ namespace Volo.Abp.Application.Services
}
/// <summary>
/// Maps <see cref="TEntity"/> to <see cref="TGetListOutputDto"/>.
/// Maps <typeparamref name="TEntity"/> to <typeparamref name="TGetListOutputDto"/>.
/// It internally calls the <see cref="MapToGetListOutputDto"/> by default.
/// It can be overriden for custom mapping.
/// Overriding this has higher priority than overriding the <see cref="MapToGetListOutputDto"/>
@ -214,7 +238,7 @@ namespace Volo.Abp.Application.Services
}
/// <summary>
/// Maps <see cref="TEntity"/> to <see cref="TGetListOutputDto"/>.
/// Maps <typeparamref name="TEntity"/> to <typeparamref name="TGetListOutputDto"/>.
/// It uses <see cref="IObjectMapper"/> by default.
/// It can be overriden for custom mapping.
/// </summary>

4
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/CrudAppService.cs

@ -80,12 +80,12 @@ namespace Volo.Abp.Application.Services
Repository = repository;
}
protected async override Task DeleteByIdAsync(TKey id)
protected override async Task DeleteByIdAsync(TKey id)
{
await Repository.DeleteAsync(id);
}
protected async override Task<TEntity> GetEntityByIdAsync(TKey id)
protected override async Task<TEntity> GetEntityByIdAsync(TKey id)
{
return await Repository.GetAsync(id);
}

4
framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ReadOnlyAppService.cs

@ -38,7 +38,7 @@ namespace Volo.Abp.Application.Services
where TGetOutputDto : IEntityDto<TKey>
where TGetListOutputDto : IEntityDto<TKey>
{
protected new IReadOnlyRepository<TEntity, TKey> Repository { get; }
protected IReadOnlyRepository<TEntity, TKey> Repository { get; }
protected ReadOnlyAppService(IReadOnlyRepository<TEntity, TKey> repository)
: base(repository)
@ -46,7 +46,7 @@ namespace Volo.Abp.Application.Services
Repository = repository;
}
protected async override Task<TEntity> GetEntityByIdAsync(TKey id)
protected override async Task<TEntity> GetEntityByIdAsync(TKey id)
{
return await Repository.GetAsync(id);
}

6
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/IAbpCommonDbContextRegistrationOptionsBuilder.cs

@ -9,11 +9,11 @@ namespace Volo.Abp.DependencyInjection
IServiceCollection Services { get; }
/// <summary>
/// Registers default repositories for this DbContext.
/// Registers default repositories for this DbContext.
/// </summary>
/// <param name="includeAllEntities">
/// Registers repositories only for aggregate root entities by default.
/// set <see cref="includeAllEntities"/> to true to include all entities.
/// set <paramref name="includeAllEntities"/> to true to include all entities.
/// </param>
IAbpCommonDbContextRegistrationOptionsBuilder AddDefaultRepositories(bool includeAllEntities = false);
@ -67,4 +67,4 @@ namespace Volo.Abp.DependencyInjection
/// <param name="otherDbContextType">The DbContext type to be replaced</param>
IAbpCommonDbContextRegistrationOptionsBuilder ReplaceDbContext(Type otherDbContextType);
}
}
}

9
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IReadOnlyRepository.cs

@ -1,6 +1,7 @@
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Linq;
@ -11,9 +12,17 @@ namespace Volo.Abp.Domain.Repositories
{
IAsyncQueryableExecuter AsyncExecuter { get; }
[Obsolete("Use WithDetailsAsync method.")]
IQueryable<TEntity> WithDetails();
[Obsolete("Use WithDetailsAsync method.")]
IQueryable<TEntity> WithDetails(params Expression<Func<TEntity, object>>[] propertySelectors);
Task<IQueryable<TEntity>> WithDetailsAsync(); //TODO: CancellationToken
Task<IQueryable<TEntity>> WithDetailsAsync(params Expression<Func<TEntity, object>>[] propertySelectors); //TODO: CancellationToken
Task<IQueryable<TEntity>> GetQueryableAsync(); //TODO: CancellationToken
}
public interface IReadOnlyRepository<TEntity, TKey> : IReadOnlyRepository<TEntity>, IReadOnlyBasicRepository<TEntity, TKey>

22
framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryBase.cs

@ -17,34 +17,54 @@ namespace Volo.Abp.Domain.Repositories
public abstract class RepositoryBase<TEntity> : BasicRepositoryBase<TEntity>, IRepository<TEntity>, IUnitOfWorkManagerAccessor
where TEntity : class, IEntity
{
[Obsolete("This method will be removed in future versions.")]
public virtual Type ElementType => GetQueryable().ElementType;
[Obsolete("This method will be removed in future versions.")]
public virtual Expression Expression => GetQueryable().Expression;
[Obsolete("This method will be removed in future versions.")]
public virtual IQueryProvider Provider => GetQueryable().Provider;
[Obsolete("Use WithDetailsAsync method.")]
public virtual IQueryable<TEntity> WithDetails()
{
return GetQueryable();
}
[Obsolete("Use WithDetailsAsync method.")]
public virtual IQueryable<TEntity> WithDetails(params Expression<Func<TEntity, object>>[] propertySelectors)
{
return GetQueryable();
}
public virtual Task<IQueryable<TEntity>> WithDetailsAsync()
{
return GetQueryableAsync();
}
public virtual Task<IQueryable<TEntity>> WithDetailsAsync(params Expression<Func<TEntity, object>>[] propertySelectors)
{
return GetQueryableAsync();
}
[Obsolete("This method will be removed in future versions.")]
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
[Obsolete("This method will be removed in future versions.")]
public IEnumerator<TEntity> GetEnumerator()
{
return GetQueryable().GetEnumerator();
}
[Obsolete("Use GetQueryableAsync method.")]
protected abstract IQueryable<TEntity> GetQueryable();
public abstract Task<IQueryable<TEntity>> GetQueryableAsync();
public abstract Task<TEntity> FindAsync(
Expression<Func<TEntity, bool>> predicate,
bool includeDetails = true,
@ -103,8 +123,6 @@ namespace Volo.Abp.Domain.Repositories
await DeleteAsync(entity, autoSave, cancellationToken);
}
public async Task DeleteManyAsync([NotNull] IEnumerable<TKey> ids, bool autoSave = false, CancellationToken cancellationToken = default)
{
foreach (var id in ids)

15
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EfCoreRepositoryExtensions.cs

@ -1,4 +1,5 @@
using System;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
@ -7,18 +8,32 @@ namespace Volo.Abp.Domain.Repositories
{
public static class EfCoreRepositoryExtensions
{
[Obsolete("Use GetDbContextAsync method.")]
public static DbContext GetDbContext<TEntity>(this IReadOnlyBasicRepository<TEntity> repository)
where TEntity : class, IEntity
{
return repository.ToEfCoreRepository().DbContext;
}
public static Task<DbContext> GetDbContextAsync<TEntity>(this IReadOnlyBasicRepository<TEntity> repository)
where TEntity : class, IEntity
{
return repository.ToEfCoreRepository().GetDbContextAsync();
}
[Obsolete("Use GetDbSetAsync method.")]
public static DbSet<TEntity> GetDbSet<TEntity>(this IReadOnlyBasicRepository<TEntity> repository)
where TEntity : class, IEntity
{
return repository.ToEfCoreRepository().DbSet;
}
public static Task<DbSet<TEntity>> GetDbSetAsync<TEntity>(this IReadOnlyBasicRepository<TEntity> repository)
where TEntity : class, IEntity
{
return repository.ToEfCoreRepository().GetDbSetAsync();
}
public static IEfCoreRepository<TEntity> ToEfCoreRepository<TEntity>(this IReadOnlyBasicRepository<TEntity> repository)
where TEntity : class, IEntity
{

178
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs

@ -1,8 +1,6 @@
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Nito.AsyncEx;
using System;
using System.Collections.Generic;
using System.Linq;
@ -21,18 +19,41 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
where TDbContext : IEfCoreDbContext
where TEntity : class, IEntity
{
public virtual DbSet<TEntity> DbSet => DbContext.Set<TEntity>();
[Obsolete("Use GetDbContextAsync() method.")]
protected virtual TDbContext DbContext => _dbContextProvider.GetDbContext();
[Obsolete("Use GetDbContextAsync() method.")]
DbContext IEfCoreRepository<TEntity>.DbContext => DbContext.As<DbContext>();
protected virtual TDbContext DbContext => _dbContextProvider.GetDbContext();
async Task<DbContext> IEfCoreRepository<TEntity>.GetDbContextAsync()
{
return await GetDbContextAsync() as DbContext;
}
protected virtual Task<TDbContext> GetDbContextAsync()
{
return _dbContextProvider.GetDbContextAsync();
}
[Obsolete("Use GetDbSetAsync() method.")]
public virtual DbSet<TEntity> DbSet => DbContext.Set<TEntity>();
Task<DbSet<TEntity>> IEfCoreRepository<TEntity>.GetDbSetAsync()
{
return GetDbSetAsync();
}
protected async Task<DbSet<TEntity>> GetDbSetAsync()
{
return (await GetDbContextAsync()).Set<TEntity>();
}
protected virtual AbpEntityOptions<TEntity> AbpEntityOptions => _entityOptionsLazy.Value;
private readonly IDbContextProvider<TDbContext> _dbContextProvider;
private readonly Lazy<AbpEntityOptions<TEntity>> _entityOptionsLazy;
public virtual IGuidGenerator GuidGenerator { get; set; }
public IGuidGenerator GuidGenerator { get; set; }
public IEfCoreBulkOperationProvider BulkOperationProvider { get; set; }
@ -49,15 +70,17 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
);
}
public async override Task<TEntity> InsertAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
public override async Task<TEntity> InsertAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
{
CheckAndSetId(entity);
var savedEntity = DbSet.Add(entity).Entity;
var dbContext = await GetDbContextAsync();
var savedEntity = (await dbContext.Set<TEntity>().AddAsync(entity, GetCancellationToken(cancellationToken))).Entity;
if (autoSave)
{
await DbContext.SaveChangesAsync(GetCancellationToken(cancellationToken));
await dbContext.SaveChangesAsync(GetCancellationToken(cancellationToken));
}
return savedEntity;
@ -65,7 +88,11 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
public override async Task InsertManyAsync(IEnumerable<TEntity> entities, bool autoSave = false, CancellationToken cancellationToken = default)
{
foreach (var entity in entities)
var entityArray = entities.ToArray();
var dbContext = await GetDbContextAsync();
cancellationToken = GetCancellationToken(cancellationToken);
foreach (var entity in entityArray)
{
CheckAndSetId(entity);
}
@ -74,30 +101,32 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
{
await BulkOperationProvider.InsertManyAsync<TDbContext, TEntity>(
this,
entities,
entityArray,
autoSave,
cancellationToken
);
return;
}
await DbSet.AddRangeAsync(entities);
await dbContext.Set<TEntity>().AddRangeAsync(entityArray, cancellationToken);
if (autoSave)
{
await DbContext.SaveChangesAsync();
await dbContext.SaveChangesAsync(cancellationToken);
}
}
public async override Task<TEntity> UpdateAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
public override async Task<TEntity> UpdateAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
{
DbContext.Attach(entity);
var dbContext = await GetDbContextAsync();
dbContext.Attach(entity);
var updatedEntity = DbContext.Update(entity).Entity;
var updatedEntity = dbContext.Update(entity).Entity;
if (autoSave)
{
await DbContext.SaveChangesAsync(GetCancellationToken(cancellationToken));
await dbContext.SaveChangesAsync(GetCancellationToken(cancellationToken));
}
return updatedEntity;
@ -105,6 +134,8 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
public override async Task UpdateManyAsync(IEnumerable<TEntity> entities, bool autoSave = false, CancellationToken cancellationToken = default)
{
cancellationToken = GetCancellationToken(cancellationToken);
if (BulkOperationProvider != null)
{
await BulkOperationProvider.UpdateManyAsync<TDbContext, TEntity>(
@ -117,65 +148,76 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
return;
}
DbSet.UpdateRange(entities);
var dbContext = await GetDbContextAsync();
dbContext.Set<TEntity>().UpdateRange(entities);
if (autoSave)
{
await DbContext.SaveChangesAsync();
await dbContext.SaveChangesAsync(cancellationToken);
}
}
public async override Task DeleteAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
public override async Task DeleteAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
{
DbSet.Remove(entity);
var dbContext = await GetDbContextAsync();
dbContext.Set<TEntity>().Remove(entity);
if (autoSave)
{
await DbContext.SaveChangesAsync(GetCancellationToken(cancellationToken));
await dbContext.SaveChangesAsync(GetCancellationToken(cancellationToken));
}
}
public override async Task DeleteManyAsync(IEnumerable<TEntity> entities, bool autoSave = false, CancellationToken cancellationToken = default)
{
cancellationToken = GetCancellationToken(cancellationToken);
if (BulkOperationProvider != null)
{
await BulkOperationProvider.DeleteManyAsync<TDbContext, TEntity>(
this,
entities,
autoSave,
cancellationToken);
cancellationToken
);
return;
}
DbSet.RemoveRange(entities);
var dbContext = await GetDbContextAsync();
dbContext.RemoveRange(entities);
if (autoSave)
{
await DbContext.SaveChangesAsync();
await dbContext.SaveChangesAsync(cancellationToken);
}
}
public async override Task<List<TEntity>> GetListAsync(bool includeDetails = false, CancellationToken cancellationToken = default)
public override async Task<List<TEntity>> GetListAsync(bool includeDetails = false, CancellationToken cancellationToken = default)
{
return includeDetails
? await WithDetails().ToListAsync(GetCancellationToken(cancellationToken))
: await DbSet.ToListAsync(GetCancellationToken(cancellationToken));
? await (await WithDetailsAsync()).ToListAsync(GetCancellationToken(cancellationToken))
: await (await GetDbSetAsync()).ToListAsync(GetCancellationToken(cancellationToken));
}
public async override Task<long> GetCountAsync(CancellationToken cancellationToken = default)
public override async Task<long> GetCountAsync(CancellationToken cancellationToken = default)
{
return await DbSet.LongCountAsync(GetCancellationToken(cancellationToken));
return await (await GetDbSetAsync()).LongCountAsync(GetCancellationToken(cancellationToken));
}
public async override Task<List<TEntity>> GetPagedListAsync(
public override async Task<List<TEntity>> GetPagedListAsync(
int skipCount,
int maxResultCount,
string sorting,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var queryable = includeDetails ? WithDetails() : DbSet;
var queryable = includeDetails
? await WithDetailsAsync()
: await GetDbSetAsync();
return await queryable
.OrderBy(sorting)
@ -183,44 +225,53 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
.ToListAsync(GetCancellationToken(cancellationToken));
}
[Obsolete("Use GetQueryableAsync method.")]
protected override IQueryable<TEntity> GetQueryable()
{
return DbSet.AsQueryable();
}
protected override Task SaveChangesAsync(CancellationToken cancellationToken)
public override async Task<IQueryable<TEntity>> GetQueryableAsync()
{
return (await GetDbSetAsync()).AsQueryable();
}
protected override async Task SaveChangesAsync(CancellationToken cancellationToken)
{
return DbContext.SaveChangesAsync(cancellationToken);
await (await GetDbContextAsync()).SaveChangesAsync(cancellationToken);
}
public async override Task<TEntity> FindAsync(
public override async Task<TEntity> FindAsync(
Expression<Func<TEntity, bool>> predicate,
bool includeDetails = true,
CancellationToken cancellationToken = default)
{
return includeDetails
? await WithDetails()
? await (await WithDetailsAsync())
.Where(predicate)
.SingleOrDefaultAsync(GetCancellationToken(cancellationToken))
: await DbSet
: await (await GetDbSetAsync())
.Where(predicate)
.SingleOrDefaultAsync(GetCancellationToken(cancellationToken));
}
public async override Task DeleteAsync(Expression<Func<TEntity, bool>> predicate, bool autoSave = false, CancellationToken cancellationToken = default)
public override async Task DeleteAsync(Expression<Func<TEntity, bool>> predicate, bool autoSave = false, CancellationToken cancellationToken = default)
{
var entities = await GetQueryable()
var dbContext = await GetDbContextAsync();
var dbSet = dbContext.Set<TEntity>();
var entities = await dbSet
.Where(predicate)
.ToListAsync(GetCancellationToken(cancellationToken));
foreach (var entity in entities)
{
DbSet.Remove(entity);
dbSet.Remove(entity);
}
if (autoSave)
{
await DbContext.SaveChangesAsync(GetCancellationToken(cancellationToken));
await dbContext.SaveChangesAsync(GetCancellationToken(cancellationToken));
}
}
@ -230,7 +281,7 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
CancellationToken cancellationToken = default)
where TProperty : class
{
await DbContext
await (await GetDbContextAsync())
.Entry(entity)
.Collection(propertyExpression)
.LoadAsync(GetCancellationToken(cancellationToken));
@ -242,12 +293,13 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
CancellationToken cancellationToken = default)
where TProperty : class
{
await DbContext
await (await GetDbContextAsync())
.Entry(entity)
.Reference(propertyExpression)
.LoadAsync(GetCancellationToken(cancellationToken));
}
[Obsolete("Use WithDetailsAsync")]
public override IQueryable<TEntity> WithDetails()
{
if (AbpEntityOptions.DefaultWithDetailsFunc == null)
@ -258,10 +310,37 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
return AbpEntityOptions.DefaultWithDetailsFunc(GetQueryable());
}
public override async Task<IQueryable<TEntity>> WithDetailsAsync()
{
if (AbpEntityOptions.DefaultWithDetailsFunc == null)
{
return await base.WithDetailsAsync();
}
return AbpEntityOptions.DefaultWithDetailsFunc(await GetQueryableAsync());
}
[Obsolete("Use WithDetailsAsync method.")]
public override IQueryable<TEntity> WithDetails(params Expression<Func<TEntity, object>>[] propertySelectors)
{
var query = GetQueryable();
return IncludeDetails(
GetQueryable(),
propertySelectors
);
}
public override async Task<IQueryable<TEntity>> WithDetailsAsync(params Expression<Func<TEntity, object>>[] propertySelectors)
{
return IncludeDetails(
await GetQueryableAsync(),
propertySelectors
);
}
private static IQueryable<TEntity> IncludeDetails(
IQueryable<TEntity> query,
Expression<Func<TEntity, object>>[] propertySelectors)
{
if (!propertySelectors.IsNullOrEmpty())
{
foreach (var propertySelector in propertySelectors)
@ -273,6 +352,7 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
return query;
}
[Obsolete("This method will be deleted in future versions.")]
public IAsyncEnumerator<TEntity> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return DbSet.AsAsyncEnumerable().GetAsyncEnumerator(cancellationToken);
@ -329,8 +409,8 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
public virtual async Task<TEntity> FindAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default)
{
return includeDetails
? await WithDetails().FirstOrDefaultAsync(e => e.Id.Equals(id), GetCancellationToken(cancellationToken))
: await DbSet.FindAsync(new object[] { id }, GetCancellationToken(cancellationToken));
? await (await WithDetailsAsync()).FirstOrDefaultAsync(e => e.Id.Equals(id), GetCancellationToken(cancellationToken))
: await (await GetDbSetAsync()).FindAsync(new object[] {id}, GetCancellationToken(cancellationToken));
}
public virtual async Task DeleteAsync(TKey id, bool autoSave = false, CancellationToken cancellationToken = default)
@ -344,9 +424,11 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
await DeleteAsync(entity, autoSave, cancellationToken);
}
public async virtual Task DeleteManyAsync([NotNull] IEnumerable<TKey> ids, bool autoSave = false, CancellationToken cancellationToken = default)
public virtual async Task DeleteManyAsync(IEnumerable<TKey> ids, bool autoSave = false, CancellationToken cancellationToken = default)
{
var entities = await DbSet.Where(x => ids.Contains(x.Id)).ToListAsync();
cancellationToken = GetCancellationToken(cancellationToken);
var entities = await (await GetDbSetAsync()).Where(x => ids.Contains(x.Id)).ToListAsync(cancellationToken);
await DeleteManyAsync(entities, autoSave, cancellationToken);
}

10
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/IEfCoreRepository.cs

@ -1,3 +1,5 @@
using System;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Entities;
@ -6,9 +8,15 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
public interface IEfCoreRepository<TEntity> : IRepository<TEntity>
where TEntity : class, IEntity
{
[Obsolete("Use GetDbContextAsync() method.")]
DbContext DbContext { get; }
[Obsolete("Use GetDbSetAsync() method.")]
DbSet<TEntity> DbSet { get; }
Task<DbContext> GetDbContextAsync();
Task<DbSet<TEntity>> GetDbSetAsync();
}
public interface IEfCoreRepository<TEntity, TKey> : IEfCoreRepository<TEntity>, IRepository<TEntity, TKey>
@ -16,4 +24,4 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
{
}
}
}

4
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/DbContextOptionsFactory.cs

@ -86,7 +86,11 @@ namespace Volo.Abp.EntityFrameworkCore.DependencyInjection
}
var connectionStringName = ConnectionStringNameAttribute.GetConnStringName<TDbContext>();
//Use DefaultConnectionStringResolver.Resolve when we remove IConnectionStringResolver.Resolve
#pragma warning disable 618
var connectionString = serviceProvider.GetRequiredService<IConnectionStringResolver>().Resolve(connectionStringName);
#pragma warning restore 618
return new DbContextCreationContext(
connectionStringName,

2
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/EfCoreAsyncQueryableProvider.cs

@ -11,7 +11,7 @@ using Volo.Abp.Linq;
namespace Volo.Abp.EntityFrameworkCore
{
public class EfCoreAsyncQueryableProvider : IAsyncQueryableProvider, ITransientDependency
public class EfCoreAsyncQueryableProvider : IAsyncQueryableProvider, ISingletonDependency
{
public bool CanExecute<T>(IQueryable<T> queryable)
{

10
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/IDbContextProvider.cs

@ -1,8 +1,14 @@
using System;
using System.Threading.Tasks;
namespace Volo.Abp.EntityFrameworkCore
{
public interface IDbContextProvider<out TDbContext>
public interface IDbContextProvider<TDbContext>
where TDbContext : IEfCoreDbContext
{
[Obsolete("Use GetDbContextAsync method.")]
TDbContext GetDbContext();
Task<TDbContext> GetDbContextAsync();
}
}
}

2
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/ObjectExtending/EfCoreObjectExtensionManagerExtensions.cs

@ -143,7 +143,9 @@ namespace Volo.Abp.ObjectExtending
var propertyBuilder = typeBuilder.Property(property.Type, property.Name);
efCoreMapping.EntityTypeAndPropertyBuildAction?.Invoke(typeBuilder, propertyBuilder);
#pragma warning disable 618
efCoreMapping.PropertyBuildAction?.Invoke(propertyBuilder);
#pragma warning restore 618
}
}
}

132
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/UnitOfWorkDbContextProvider.cs

@ -1,11 +1,15 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.DependencyInjection;
using Volo.Abp.Threading;
namespace Volo.Abp.Uow.EntityFrameworkCore
{
@ -14,19 +18,34 @@ namespace Volo.Abp.Uow.EntityFrameworkCore
public class UnitOfWorkDbContextProvider<TDbContext> : IDbContextProvider<TDbContext>
where TDbContext : IEfCoreDbContext
{
public ILogger<UnitOfWorkDbContextProvider<TDbContext>> Logger { get; set; }
private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly IConnectionStringResolver _connectionStringResolver;
private readonly ICancellationTokenProvider _cancellationTokenProvider;
public UnitOfWorkDbContextProvider(
IUnitOfWorkManager unitOfWorkManager,
IConnectionStringResolver connectionStringResolver)
IConnectionStringResolver connectionStringResolver,
ICancellationTokenProvider cancellationTokenProvider)
{
_unitOfWorkManager = unitOfWorkManager;
_connectionStringResolver = connectionStringResolver;
_cancellationTokenProvider = cancellationTokenProvider;
Logger = NullLogger<UnitOfWorkDbContextProvider<TDbContext>>.Instance;
}
[Obsolete("Use GetDbContextAsync method.")]
public TDbContext GetDbContext()
{
Logger.LogWarning(
"UnitOfWorkDbContextProvider.GetDbContext is deprecated. Use GetDbContextAsync instead! " +
"You are probably using LINQ (LINQ extensions) directly on a repository. In this case, use repository.GetQueryableAsync() method " +
"to obtain an IQueryable<T> instance and use LINQ (LINQ extensions) on this object. "
);
Logger.LogWarning(Environment.StackTrace.Truncate(2048));
var unitOfWork = _unitOfWorkManager.Current;
if (unitOfWork == null)
{
@ -47,6 +66,33 @@ namespace Volo.Abp.Uow.EntityFrameworkCore
return ((EfCoreDatabaseApi<TDbContext>)databaseApi).DbContext;
}
public async Task<TDbContext> GetDbContextAsync()
{
var unitOfWork = _unitOfWorkManager.Current;
if (unitOfWork == null)
{
throw new AbpException("A DbContext can only be created inside a unit of work!");
}
var connectionStringName = ConnectionStringNameAttribute.GetConnStringName<TDbContext>();
var connectionString = await _connectionStringResolver.ResolveAsync(connectionStringName);
var dbContextKey = $"{typeof(TDbContext).FullName}_{connectionString}";
var databaseApi = unitOfWork.FindDatabaseApi(dbContextKey);
if (databaseApi == null)
{
databaseApi = new EfCoreDatabaseApi<TDbContext>(
await CreateDbContextAsync(unitOfWork, connectionStringName, connectionString)
);
unitOfWork.AddDatabaseApi(dbContextKey, databaseApi);
}
return ((EfCoreDatabaseApi<TDbContext>)databaseApi).DbContext;
}
private TDbContext CreateDbContext(IUnitOfWork unitOfWork, string connectionStringName, string connectionString)
{
var creationContext = new DbContextCreationContext(connectionStringName, connectionString);
@ -67,6 +113,26 @@ namespace Volo.Abp.Uow.EntityFrameworkCore
}
}
private async Task<TDbContext> CreateDbContextAsync(IUnitOfWork unitOfWork, string connectionStringName, string connectionString)
{
var creationContext = new DbContextCreationContext(connectionStringName, connectionString);
using (DbContextCreationContext.Use(creationContext))
{
var dbContext = await CreateDbContextAsync(unitOfWork);
if (dbContext is IAbpEfCoreDbContext abpEfCoreDbContext)
{
abpEfCoreDbContext.Initialize(
new AbpEfCoreDbContextInitializationContext(
unitOfWork
)
);
}
return dbContext;
}
}
private TDbContext CreateDbContext(IUnitOfWork unitOfWork)
{
return unitOfWork.Options.IsTransactional
@ -74,7 +140,16 @@ namespace Volo.Abp.Uow.EntityFrameworkCore
: unitOfWork.ServiceProvider.GetRequiredService<TDbContext>();
}
public TDbContext CreateDbContextWithTransaction(IUnitOfWork unitOfWork)
private async Task<TDbContext> CreateDbContextAsync(IUnitOfWork unitOfWork)
{
Logger.LogDebug($"Creating a new DbContext of type {typeof(TDbContext).FullName}");
return unitOfWork.Options.IsTransactional
? await CreateDbContextWithTransactionAsync(unitOfWork)
: unitOfWork.ServiceProvider.GetRequiredService<TDbContext>();
}
private TDbContext CreateDbContextWithTransaction(IUnitOfWork unitOfWork)
{
var transactionApiKey = $"EntityFrameworkCore_{DbContextCreationContext.Current.ConnectionString}";
var activeTransaction = unitOfWork.FindTransactionApi(transactionApiKey) as EfCoreTransactionApi;
@ -117,5 +192,54 @@ namespace Volo.Abp.Uow.EntityFrameworkCore
return dbContext;
}
}
private async Task<TDbContext> CreateDbContextWithTransactionAsync(IUnitOfWork unitOfWork)
{
var transactionApiKey = $"EntityFrameworkCore_{DbContextCreationContext.Current.ConnectionString}";
var activeTransaction = unitOfWork.FindTransactionApi(transactionApiKey) as EfCoreTransactionApi;
if (activeTransaction == null)
{
var dbContext = unitOfWork.ServiceProvider.GetRequiredService<TDbContext>();
var dbTransaction = unitOfWork.Options.IsolationLevel.HasValue
? await dbContext.Database.BeginTransactionAsync(unitOfWork.Options.IsolationLevel.Value, GetCancellationToken())
: await dbContext.Database.BeginTransactionAsync(GetCancellationToken());
unitOfWork.AddTransactionApi(
transactionApiKey,
new EfCoreTransactionApi(
dbTransaction,
dbContext
)
);
return dbContext;
}
else
{
DbContextCreationContext.Current.ExistingConnection = activeTransaction.DbContextTransaction.GetDbTransaction().Connection;
var dbContext = unitOfWork.ServiceProvider.GetRequiredService<TDbContext>();
if (dbContext.As<DbContext>().HasRelationalTransactionManager())
{
await dbContext.Database.UseTransactionAsync(activeTransaction.DbContextTransaction.GetDbTransaction(), GetCancellationToken());
}
else
{
await dbContext.Database.BeginTransactionAsync(GetCancellationToken()); //TODO: Why not using the new created transaction?
}
activeTransaction.AttendedDbContexts.Add(dbContext);
return dbContext;
}
}
protected virtual CancellationToken GetCancellationToken(CancellationToken preferredValue = default)
{
return _cancellationTokenProvider.FallbackToProvider(preferredValue);
}
}
}
}

4
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventBus.cs

@ -33,7 +33,7 @@ namespace Volo.Abp.EventBus
/// <summary>
/// Registers to an event.
/// A new instance of <see cref="THandler"/> object is created for every event occurrence.
/// A new instance of <typeparamref name="THandler"/> object is created for every event occurrence.
/// </summary>
/// <typeparam name="TEvent">Event type</typeparam>
/// <typeparam name="THandler">Type of the event handler</typeparam>
@ -116,4 +116,4 @@ namespace Volo.Abp.EventBus
/// <param name="eventType">Event type</param>
void UnsubscribeAll(Type eventType);
}
}
}

4
framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventDataMayHaveTenantId.cs

@ -16,8 +16,8 @@ namespace Volo.Abp.EventBus
{
/// <summary>
/// Returns true if this event data has a Tenant Id information.
/// If so, it should set the <see cref="tenantId"/> our parameter.
/// Otherwise, the <see cref="tenantId"/> our parameter value should not be informative
/// If so, it should set the <paramref name="tenantId"/> our parameter.
/// Otherwise, the <paramref name="tenantId"/> our parameter value should not be informative
/// (it will be null as expected, but doesn't indicate a tenant with null tenant id).
/// </summary>
/// <param name="tenantId">

4
framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureDefinition.cs

@ -69,8 +69,8 @@ namespace Volo.Abp.Features
/// </summary>
/// <param name="name">Name of the property</param>
/// <returns>
/// Returns the value in the <see cref="Properties"/> dictionary by given <see cref="name"/>.
/// Returns null if given <see cref="name"/> is not present in the <see cref="Properties"/> dictionary.
/// Returns the value in the <see cref="Properties"/> dictionary by given <paramref name="name"/>.
/// Returns null if given <paramref name="name"/> is not present in the <see cref="Properties"/> dictionary.
/// </returns>
[CanBeNull]
public object this[string name]

8
framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureGroupDefinition.cs

@ -29,8 +29,8 @@ namespace Volo.Abp.Features
/// </summary>
/// <param name="name">Name of the property</param>
/// <returns>
/// Returns the value in the <see cref="Properties"/> dictionary by given <see cref="name"/>.
/// Returns null if given <see cref="name"/> is not present in the <see cref="Properties"/> dictionary.
/// Returns the value in the <see cref="Properties"/> dictionary by given <paramref name="name"/>.
/// Returns null if given <paramref name="name"/> is not present in the <see cref="Properties"/> dictionary.
/// </returns>
public object this[string name]
{
@ -39,7 +39,7 @@ namespace Volo.Abp.Features
}
protected internal FeatureGroupDefinition(
string name,
string name,
ILocalizableString displayName = null)
{
Name = name;
@ -108,4 +108,4 @@ namespace Volo.Abp.Features
return $"[{nameof(FeatureGroupDefinition)} {Name}]";
}
}
}
}

9
framework/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/IMemoryDbRepository.cs

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Threading.Tasks;
using Volo.Abp.Domain.Entities;
namespace Volo.Abp.Domain.Repositories.MemoryDb
@ -6,9 +7,15 @@ namespace Volo.Abp.Domain.Repositories.MemoryDb
public interface IMemoryDbRepository<TEntity> : IRepository<TEntity>
where TEntity : class, IEntity
{
[Obsolete("Use GetDatabaseAsync() method.")]
IMemoryDatabase Database { get; }
[Obsolete("Use GetCollectionAsync() method.")]
IMemoryDatabaseCollection<TEntity> Collection { get; }
Task<IMemoryDatabase> GetDatabaseAsync();
Task<IMemoryDatabaseCollection<TEntity>> GetCollectionAsync();
}
public interface IMemoryDbRepository<TEntity, TKey> : IMemoryDbRepository<TEntity>, IRepository<TEntity, TKey>

77
framework/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDbRepository.cs

@ -1,4 +1,3 @@
using JetBrains.Annotations;
using System;
using System.Collections.Generic;
using System.Linq;
@ -22,10 +21,22 @@ namespace Volo.Abp.Domain.Repositories.MemoryDb
{
//TODO: Add dbcontext just like mongodb implementation!
[Obsolete("Use GetCollectionAsync method.")]
public virtual IMemoryDatabaseCollection<TEntity> Collection => Database.Collection<TEntity>();
public async Task<IMemoryDatabaseCollection<TEntity>> GetCollectionAsync()
{
return (await GetDatabaseAsync()).Collection<TEntity>();
}
[Obsolete("Use GetDatabaseAsync method.")]
public virtual IMemoryDatabase Database => DatabaseProvider.GetDatabase();
public Task<IMemoryDatabase> GetDatabaseAsync()
{
return DatabaseProvider.GetDatabaseAsync();
}
protected IMemoryDatabaseProvider<TMemoryDbContext> DatabaseProvider { get; }
public ILocalEventBus LocalEventBus { get; set; }
@ -47,11 +58,17 @@ namespace Volo.Abp.Domain.Repositories.MemoryDb
EntityChangeEventHelper = NullEntityChangeEventHelper.Instance;
}
[Obsolete("This method will be removed in future versions.")]
protected override IQueryable<TEntity> GetQueryable()
{
return ApplyDataFilters(Collection.AsQueryable());
}
public override async Task<IQueryable<TEntity>> GetQueryableAsync()
{
return ApplyDataFilters((await GetCollectionAsync()).AsQueryable());
}
protected virtual async Task TriggerDomainEventsAsync(object entity)
{
var generatesDomainEventsEntity = entity as IGeneratesDomainEvents;
@ -163,39 +180,40 @@ namespace Volo.Abp.Domain.Repositories.MemoryDb
await TriggerDomainEventsAsync(entity);
}
public override Task<TEntity> FindAsync(
public override async Task<TEntity> FindAsync(
Expression<Func<TEntity, bool>> predicate,
bool includeDetails = true,
CancellationToken cancellationToken = default)
{
return Task.FromResult(GetQueryable().Where(predicate).SingleOrDefault());
return (await GetQueryableAsync()).Where(predicate).SingleOrDefault();
}
public async override Task DeleteAsync(
public override async Task DeleteAsync(
Expression<Func<TEntity, bool>> predicate,
bool autoSave = false,
CancellationToken cancellationToken = default)
{
var entities = GetQueryable().Where(predicate).ToList();
var entities = (await GetQueryableAsync()).Where(predicate).ToList();
foreach (var entity in entities)
{
await DeleteAsync(entity, autoSave, cancellationToken);
}
}
public async override Task<TEntity> InsertAsync(
public override async Task<TEntity> InsertAsync(
TEntity entity,
bool autoSave = false,
CancellationToken cancellationToken = default)
{
await ApplyAbpConceptsForAddedEntityAsync(entity);
Collection.Add(entity);
(await GetCollectionAsync()).Add(entity);
return entity;
}
public async override Task<TEntity> UpdateAsync(
public override async Task<TEntity> UpdateAsync(
TEntity entity,
bool autoSave = false,
CancellationToken cancellationToken = default)
@ -214,12 +232,12 @@ namespace Volo.Abp.Domain.Repositories.MemoryDb
await TriggerDomainEventsAsync(entity);
Collection.Update(entity);
(await GetCollectionAsync()).Update(entity);
return entity;
}
public async override Task DeleteAsync(
public override async Task DeleteAsync(
TEntity entity,
bool autoSave = false,
CancellationToken cancellationToken = default)
@ -229,35 +247,35 @@ namespace Volo.Abp.Domain.Repositories.MemoryDb
if (entity is ISoftDelete softDeleteEntity && !IsHardDeleted(entity))
{
softDeleteEntity.IsDeleted = true;
Collection.Update(entity);
(await GetCollectionAsync()).Update(entity);
}
else
{
Collection.Remove(entity);
(await GetCollectionAsync()).Remove(entity);
}
}
public override Task<List<TEntity>> GetListAsync(bool includeDetails = false, CancellationToken cancellationToken = default)
public override async Task<List<TEntity>> GetListAsync(bool includeDetails = false, CancellationToken cancellationToken = default)
{
return Task.FromResult(GetQueryable().ToList());
return (await GetQueryableAsync()).ToList();
}
public override Task<long> GetCountAsync(CancellationToken cancellationToken = default)
public override async Task<long> GetCountAsync(CancellationToken cancellationToken = default)
{
return Task.FromResult(GetQueryable().LongCount());
return (await GetQueryableAsync()).LongCount();
}
public override Task<List<TEntity>> GetPagedListAsync(
public override async Task<List<TEntity>> GetPagedListAsync(
int skipCount,
int maxResultCount,
string sorting,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return Task.FromResult(GetQueryable()
return (await GetQueryableAsync())
.OrderBy(sorting)
.PageBy(skipCount, maxResultCount)
.ToList());
.ToList();
}
}
@ -270,13 +288,13 @@ namespace Volo.Abp.Domain.Repositories.MemoryDb
{
}
public override Task<TEntity> InsertAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
public override async Task<TEntity> InsertAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
{
SetIdIfNeeded(entity);
return base.InsertAsync(entity, autoSave, cancellationToken);
await SetIdIfNeededAsync(entity);
return await base.InsertAsync(entity, autoSave, cancellationToken);
}
protected virtual void SetIdIfNeeded(TEntity entity)
protected virtual async Task SetIdIfNeededAsync(TEntity entity)
{
if (typeof(TKey) == typeof(int) ||
typeof(TKey) == typeof(long) ||
@ -284,7 +302,8 @@ namespace Volo.Abp.Domain.Repositories.MemoryDb
{
if (EntityHelper.HasDefaultId(entity))
{
EntityHelper.TrySetId(entity, () => Database.GenerateNextId<TEntity, TKey>());
var nextId = (await GetDatabaseAsync()).GenerateNextId<TEntity, TKey>();
EntityHelper.TrySetId(entity, () => nextId);
}
}
}
@ -301,9 +320,9 @@ namespace Volo.Abp.Domain.Repositories.MemoryDb
return entity;
}
public virtual Task<TEntity> FindAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default)
public virtual async Task<TEntity> FindAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default)
{
return Task.FromResult(GetQueryable().FirstOrDefault(e => e.Id.Equals(id)));
return (await GetQueryableAsync()).FirstOrDefault(e => e.Id.Equals(id));
}
public virtual async Task DeleteAsync(TKey id, bool autoSave = false, CancellationToken cancellationToken = default)
@ -311,10 +330,10 @@ namespace Volo.Abp.Domain.Repositories.MemoryDb
await DeleteAsync(x => x.Id.Equals(id), autoSave, cancellationToken);
}
public virtual async Task DeleteManyAsync([NotNull] IEnumerable<TKey> ids, bool autoSave = false, CancellationToken cancellationToken = default)
public virtual async Task DeleteManyAsync(IEnumerable<TKey> ids, bool autoSave = false, CancellationToken cancellationToken = default)
{
var entities = await AsyncExecuter.ToListAsync(GetQueryable().Where(x => ids.Contains(x.Id)));
DeleteManyAsync(entities, autoSave, cancellationToken);
var entities = await AsyncExecuter.ToListAsync((await GetQueryableAsync()).Where(x => ids.Contains(x.Id)), cancellationToken);
await DeleteManyAsync(entities, autoSave, cancellationToken);
}
}
}

17
framework/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDbCoreRepositoryExtensions.cs

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories.MemoryDb;
@ -7,18 +8,32 @@ namespace Volo.Abp.Domain.Repositories
{
public static class MemoryDbCoreRepositoryExtensions
{
[Obsolete("Use GetDatabaseAsync method.")]
public static IMemoryDatabase GetDatabase<TEntity, TKey>(this IBasicRepository<TEntity, TKey> repository)
where TEntity : class, IEntity<TKey>
{
return repository.ToMemoryDbRepository().Database;
}
public static Task<IMemoryDatabase> GetDatabaseAsync<TEntity, TKey>(this IBasicRepository<TEntity, TKey> repository)
where TEntity : class, IEntity<TKey>
{
return repository.ToMemoryDbRepository().GetDatabaseAsync();
}
[Obsolete("Use GetCollectionAsync method.")]
public static IMemoryDatabaseCollection<TEntity> GetCollection<TEntity, TKey>(this IBasicRepository<TEntity, TKey> repository)
where TEntity : class, IEntity<TKey>
{
return repository.ToMemoryDbRepository().Collection;
}
public static Task<IMemoryDatabaseCollection<TEntity>> GetCollectionAsync<TEntity, TKey>(this IBasicRepository<TEntity, TKey> repository)
where TEntity : class, IEntity<TKey>
{
return repository.ToMemoryDbRepository().GetCollectionAsync();
}
public static IMemoryDbRepository<TEntity, TKey> ToMemoryDbRepository<TEntity, TKey>(this IBasicRepository<TEntity, TKey> repository)
where TEntity : class, IEntity<TKey>
{
@ -31,4 +46,4 @@ namespace Volo.Abp.Domain.Repositories
return memoryDbRepository;
}
}
}
}

12
framework/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/IMemoryDatabaseProvider.cs

@ -1,12 +1,20 @@
using Volo.Abp.Domain.Repositories.MemoryDb;
using System;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories.MemoryDb;
namespace Volo.Abp.MemoryDb
{
public interface IMemoryDatabaseProvider<TMemoryDbContext>
where TMemoryDbContext : MemoryDbContext
{
[Obsolete("Use GetDbContextAsync method.")]
TMemoryDbContext DbContext { get; }
Task<TMemoryDbContext> GetDbContextAsync();
[Obsolete("Use GetDatabaseAsync method.")]
IMemoryDatabase GetDatabase();
Task<IMemoryDatabase> GetDatabaseAsync();
}
}
}

36
framework/src/Volo.Abp.MemoryDb/Volo/Abp/Uow/MemoryDb/UnitOfWorkMemoryDatabaseProvider.cs

@ -1,4 +1,6 @@
using Volo.Abp.Data;
using System;
using System.Threading.Tasks;
using Volo.Abp.Data;
using Volo.Abp.Domain.Repositories.MemoryDb;
using Volo.Abp.MemoryDb;
@ -8,7 +10,7 @@ namespace Volo.Abp.Uow.MemoryDb
where TMemoryDbContext : MemoryDbContext
{
public TMemoryDbContext DbContext { get; }
private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly IConnectionStringResolver _connectionStringResolver;
private readonly MemoryDatabaseManager _memoryDatabaseManager;
@ -16,7 +18,7 @@ namespace Volo.Abp.Uow.MemoryDb
public UnitOfWorkMemoryDatabaseProvider(
IUnitOfWorkManager unitOfWorkManager,
IConnectionStringResolver connectionStringResolver,
TMemoryDbContext dbContext,
TMemoryDbContext dbContext,
MemoryDatabaseManager memoryDatabaseManager)
{
_unitOfWorkManager = unitOfWorkManager;
@ -25,6 +27,12 @@ namespace Volo.Abp.Uow.MemoryDb
_memoryDatabaseManager = memoryDatabaseManager;
}
public Task<TMemoryDbContext> GetDbContextAsync()
{
return Task.FromResult(DbContext);
}
[Obsolete("Use GetDatabaseAsync method.")]
public IMemoryDatabase GetDatabase()
{
var unitOfWork = _unitOfWorkManager.Current;
@ -44,5 +52,25 @@ namespace Volo.Abp.Uow.MemoryDb
return ((MemoryDbDatabaseApi)databaseApi).Database;
}
public async Task<IMemoryDatabase> GetDatabaseAsync()
{
var unitOfWork = _unitOfWorkManager.Current;
if (unitOfWork == null)
{
throw new AbpException($"A {nameof(IMemoryDatabase)} instance can only be created inside a unit of work!");
}
var connectionString = await _connectionStringResolver.ResolveAsync<TMemoryDbContext>();
var dbContextKey = $"{typeof(TMemoryDbContext).FullName}_{connectionString}";
var databaseApi = unitOfWork.GetOrAddDatabaseApi(
dbContextKey,
() => new MemoryDbDatabaseApi(
_memoryDatabaseManager.Get(connectionString)
));
return ((MemoryDbDatabaseApi)databaseApi).Database;
}
}
}
}

14
framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/IMongoDbRepository.cs

@ -1,4 +1,7 @@
using MongoDB.Driver;
using System;
using System.Threading;
using System.Threading.Tasks;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using Volo.Abp.Domain.Entities;
@ -7,11 +10,20 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
public interface IMongoDbRepository<TEntity> : IRepository<TEntity>
where TEntity : class, IEntity
{
[Obsolete("Use GetDatabaseAsync method.")]
IMongoDatabase Database { get; }
Task<IMongoDatabase> GetDatabaseAsync(CancellationToken cancellationToken = default);
[Obsolete("Use GetCollectionAsync method.")]
IMongoCollection<TEntity> Collection { get; }
Task<IMongoCollection<TEntity>> GetCollectionAsync(CancellationToken cancellationToken = default);
[Obsolete("Use GetMongoQueryableAsync method.")]
IMongoQueryable<TEntity> GetMongoQueryable();
Task<IMongoQueryable<TEntity>> GetMongoQueryableAsync(CancellationToken cancellationToken = default);
}
public interface IMongoDbRepository<TEntity, TKey> : IMongoDbRepository<TEntity>, IRepository<TEntity, TKey>

253
framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs

@ -27,13 +27,37 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
where TMongoDbContext : IAbpMongoDbContext
where TEntity : class, IEntity
{
[Obsolete("Use GetCollectionAsync method.")]
public virtual IMongoCollection<TEntity> Collection => DbContext.Collection<TEntity>();
public async Task<IMongoCollection<TEntity>> GetCollectionAsync(CancellationToken cancellationToken = default)
{
return (await GetDbContextAsync(GetCancellationToken(cancellationToken))).Collection<TEntity>();
}
[Obsolete("Use GetDatabaseAsync method.")]
public virtual IMongoDatabase Database => DbContext.Database;
public virtual IClientSessionHandle SessionHandle => DbContext.SessionHandle;
public async Task<IMongoDatabase> GetDatabaseAsync(CancellationToken cancellationToken = default)
{
return (await GetDbContextAsync(GetCancellationToken(cancellationToken))).Database;
}
[Obsolete("Use GetSessionHandleAsync method.")]
protected virtual IClientSessionHandle SessionHandle => DbContext.SessionHandle;
public virtual TMongoDbContext DbContext => DbContextProvider.GetDbContext();
protected async Task<IClientSessionHandle> GetSessionHandleAsync(CancellationToken cancellationToken = default)
{
return (await GetDbContextAsync(GetCancellationToken(cancellationToken))).SessionHandle;
}
[Obsolete("Use GetDbContextAsync method.")]
protected virtual TMongoDbContext DbContext => DbContextProvider.GetDbContext();
protected Task<TMongoDbContext> GetDbContextAsync(CancellationToken cancellationToken = default)
{
return DbContextProvider.GetDbContextAsync(GetCancellationToken(cancellationToken));
}
protected IMongoDbContextProvider<TMongoDbContext> DbContextProvider { get; }
@ -59,24 +83,27 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
GuidGenerator = SimpleGuidGenerator.Instance;
}
public async override Task<TEntity> InsertAsync(
public override async Task<TEntity> InsertAsync(
TEntity entity,
bool autoSave = false,
CancellationToken cancellationToken = default)
{
await ApplyAbpConceptsForAddedEntityAsync(entity);
if (SessionHandle != null)
var dbContext = await GetDbContextAsync(GetCancellationToken(cancellationToken));
var collection = dbContext.Collection<TEntity>();
if (dbContext.SessionHandle != null)
{
await Collection.InsertOneAsync(
SessionHandle,
await collection.InsertOneAsync(
dbContext.SessionHandle,
entity,
cancellationToken: GetCancellationToken(cancellationToken)
);
}
else
{
await Collection.InsertOneAsync(
await collection.InsertOneAsync(
entity,
cancellationToken: GetCancellationToken(cancellationToken)
);
@ -87,33 +114,38 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
public override async Task InsertManyAsync(IEnumerable<TEntity> entities, bool autoSave = false, CancellationToken cancellationToken = default)
{
foreach (var entity in entities)
var entityArray = entities.ToArray();
foreach (var entity in entityArray)
{
await ApplyAbpConceptsForAddedEntityAsync(entity);
}
var dbContext = await GetDbContextAsync(GetCancellationToken(cancellationToken));
var collection = dbContext.Collection<TEntity>();
if (BulkOperationProvider != null)
{
await BulkOperationProvider.InsertManyAsync(this, entities, SessionHandle, autoSave, cancellationToken);
await BulkOperationProvider.InsertManyAsync(this, entityArray, dbContext.SessionHandle, autoSave, cancellationToken);
return;
}
if (SessionHandle != null)
if (dbContext.SessionHandle != null)
{
await Collection.InsertManyAsync(
SessionHandle,
entities,
await collection.InsertManyAsync(
dbContext.SessionHandle,
entityArray,
cancellationToken: cancellationToken);
}
else
{
await Collection.InsertManyAsync(
entities,
await collection.InsertManyAsync(
entityArray,
cancellationToken: cancellationToken);
}
}
public async override Task<TEntity> UpdateAsync(
public override async Task<TEntity> UpdateAsync(
TEntity entity,
bool autoSave = false,
CancellationToken cancellationToken = default)
@ -135,20 +167,21 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
var oldConcurrencyStamp = SetNewConcurrencyStamp(entity);
ReplaceOneResult result;
if (SessionHandle != null)
var dbContext = await GetDbContextAsync(GetCancellationToken(cancellationToken));
var collection = dbContext.Collection<TEntity>();
if (dbContext.SessionHandle != null)
{
result = await Collection.ReplaceOneAsync(
SessionHandle,
result = await collection.ReplaceOneAsync(
dbContext.SessionHandle,
CreateEntityFilter(entity, true, oldConcurrencyStamp),
entity,
cancellationToken: GetCancellationToken(cancellationToken)
);
}
else
{
result = await Collection.ReplaceOneAsync(
result = await collection.ReplaceOneAsync(
CreateEntityFilter(entity, true, oldConcurrencyStamp),
entity,
cancellationToken: GetCancellationToken(cancellationToken)
@ -165,12 +198,13 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
public override async Task UpdateManyAsync(IEnumerable<TEntity> entities, bool autoSave = false, CancellationToken cancellationToken = default)
{
var isSoftDeleteEntity = typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity));
var entityArray = entities.ToArray();
foreach (var entity in entities)
foreach (var entity in entityArray)
{
SetModificationAuditProperties(entity);
var isSoftDeleteEntity = typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity));
if (isSoftDeleteEntity)
{
SetDeletionAuditProperties(entity);
@ -186,37 +220,40 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
SetNewConcurrencyStamp(entity);
}
cancellationToken = GetCancellationToken(cancellationToken);
var dbContext = await GetDbContextAsync(cancellationToken);
if (BulkOperationProvider != null)
{
await BulkOperationProvider.UpdateManyAsync(this, entities, SessionHandle, autoSave, cancellationToken);
await BulkOperationProvider.UpdateManyAsync(this, entityArray, dbContext.SessionHandle, autoSave, cancellationToken);
return;
}
var entitiesCount = entities.Count();
BulkWriteResult result;
List<WriteModel<TEntity>> replaceRequests = new List<WriteModel<TEntity>>();
foreach (var entity in entities)
foreach (var entity in entityArray)
{
replaceRequests.Add(new ReplaceOneModel<TEntity>(CreateEntityFilter(entity), entity));
}
if (SessionHandle != null)
var collection = dbContext.Collection<TEntity>();
if (dbContext.SessionHandle != null)
{
result = await Collection.BulkWriteAsync(SessionHandle, replaceRequests);
result = await collection.BulkWriteAsync(dbContext.SessionHandle, replaceRequests, cancellationToken: cancellationToken);
}
else
{
result = await Collection.BulkWriteAsync(replaceRequests);
result = await collection.BulkWriteAsync(replaceRequests, cancellationToken: cancellationToken);
}
if (result.MatchedCount < entitiesCount)
if (result.MatchedCount < entityArray.Length)
{
ThrowOptimisticConcurrencyException();
}
}
public async override Task DeleteAsync(
public override async Task DeleteAsync(
TEntity entity,
bool autoSave = false,
CancellationToken cancellationToken = default)
@ -224,15 +261,18 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
await ApplyAbpConceptsForDeletedEntityAsync(entity);
var oldConcurrencyStamp = SetNewConcurrencyStamp(entity);
var dbContext = await GetDbContextAsync(GetCancellationToken(cancellationToken));
var collection = dbContext.Collection<TEntity>();
if (entity is ISoftDelete softDeleteEntity && !IsHardDeleted(entity))
{
softDeleteEntity.IsDeleted = true;
ReplaceOneResult result;
if (SessionHandle != null)
if (dbContext.SessionHandle != null)
{
result = await Collection.ReplaceOneAsync(
SessionHandle,
result = await collection.ReplaceOneAsync(
dbContext.SessionHandle,
CreateEntityFilter(entity, true, oldConcurrencyStamp),
entity,
cancellationToken: GetCancellationToken(cancellationToken)
@ -240,7 +280,7 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
}
else
{
result = await Collection.ReplaceOneAsync(
result = await collection.ReplaceOneAsync(
CreateEntityFilter(entity, true, oldConcurrencyStamp),
entity,
cancellationToken: GetCancellationToken(cancellationToken)
@ -256,17 +296,17 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
{
DeleteResult result;
if (SessionHandle != null)
if (dbContext.SessionHandle != null)
{
result = await Collection.DeleteOneAsync(
SessionHandle,
result = await collection.DeleteOneAsync(
dbContext.SessionHandle,
CreateEntityFilter(entity, true, oldConcurrencyStamp),
cancellationToken: GetCancellationToken(cancellationToken)
);
}
else
{
result = await Collection.DeleteOneAsync(
result = await collection.DeleteOneAsync(
CreateEntityFilter(entity, true, oldConcurrencyStamp),
GetCancellationToken(cancellationToken)
);
@ -284,35 +324,40 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
bool autoSave = false,
CancellationToken cancellationToken = default)
{
foreach (var entity in entities)
var entityArray = entities.ToArray();
foreach (var entity in entityArray)
{
await ApplyAbpConceptsForDeletedEntityAsync(entity);
var oldConcurrencyStamp = SetNewConcurrencyStamp(entity);
SetNewConcurrencyStamp(entity);
}
var dbContext = await GetDbContextAsync(GetCancellationToken(cancellationToken));
var collection = dbContext.Collection<TEntity>();
if (BulkOperationProvider != null)
{
await BulkOperationProvider.DeleteManyAsync(this, entities, SessionHandle, autoSave, cancellationToken);
await BulkOperationProvider.DeleteManyAsync(this, entityArray, dbContext.SessionHandle, autoSave, cancellationToken);
return;
}
var entitiesCount = entities.Count();
var entitiesCount = entityArray.Count();
if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity)))
{
UpdateResult updateResult;
if (SessionHandle != null)
if (dbContext.SessionHandle != null)
{
updateResult = await Collection.UpdateManyAsync(
SessionHandle,
CreateEntitiesFilter(entities),
updateResult = await collection.UpdateManyAsync(
dbContext.SessionHandle,
CreateEntitiesFilter(entityArray),
Builders<TEntity>.Update.Set(x => ((ISoftDelete)x).IsDeleted, true)
);
}
else
{
updateResult = await Collection.UpdateManyAsync(
CreateEntitiesFilter(entities),
updateResult = await collection.UpdateManyAsync(
CreateEntitiesFilter(entityArray),
Builders<TEntity>.Update.Set(x => ((ISoftDelete)x).IsDeleted, true)
);
}
@ -325,17 +370,17 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
else
{
DeleteResult deleteResult;
if (SessionHandle != null)
if (dbContext.SessionHandle != null)
{
deleteResult = await Collection.DeleteManyAsync(
SessionHandle,
CreateEntitiesFilter(entities)
deleteResult = await collection.DeleteManyAsync(
dbContext.SessionHandle,
CreateEntitiesFilter(entityArray)
);
}
else
{
deleteResult = await Collection.DeleteManyAsync(
CreateEntitiesFilter(entities)
deleteResult = await collection.DeleteManyAsync(
CreateEntitiesFilter(entityArray)
);
}
@ -346,38 +391,44 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
}
}
public async override Task<List<TEntity>> GetListAsync(bool includeDetails = false, CancellationToken cancellationToken = default)
public override async Task<List<TEntity>> GetListAsync(bool includeDetails = false, CancellationToken cancellationToken = default)
{
return await GetMongoQueryable().ToListAsync(GetCancellationToken(cancellationToken));
cancellationToken = GetCancellationToken(cancellationToken);
return await (await GetMongoQueryableAsync(cancellationToken)).ToListAsync(cancellationToken);
}
public async override Task<long> GetCountAsync(CancellationToken cancellationToken = default)
public override async Task<long> GetCountAsync(CancellationToken cancellationToken = default)
{
return await GetMongoQueryable().LongCountAsync(GetCancellationToken(cancellationToken));
cancellationToken = GetCancellationToken(cancellationToken);
return await (await GetMongoQueryableAsync(cancellationToken)).LongCountAsync(cancellationToken);
}
public async override Task<List<TEntity>> GetPagedListAsync(
public override async Task<List<TEntity>> GetPagedListAsync(
int skipCount,
int maxResultCount,
string sorting,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return await GetMongoQueryable()
cancellationToken = GetCancellationToken(cancellationToken);
return await (await GetMongoQueryableAsync(cancellationToken))
.OrderBy(sorting)
.As<IMongoQueryable<TEntity>>()
.PageBy<TEntity, IMongoQueryable<TEntity>>(skipCount, maxResultCount)
.ToListAsync(GetCancellationToken(cancellationToken));
.ToListAsync(cancellationToken);
}
public async override Task DeleteAsync(
public override async Task DeleteAsync(
Expression<Func<TEntity, bool>> predicate,
bool autoSave = false,
CancellationToken cancellationToken = default)
{
var entities = await GetMongoQueryable()
cancellationToken = GetCancellationToken(cancellationToken);
var entities = await (await GetMongoQueryableAsync(cancellationToken))
.Where(predicate)
.ToListAsync(GetCancellationToken(cancellationToken));
.ToListAsync(cancellationToken);
foreach (var entity in entities)
{
@ -385,25 +436,49 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
}
}
[Obsolete("Use GetQueryableAsync method.")]
protected override IQueryable<TEntity> GetQueryable()
{
return GetMongoQueryable();
}
public async override Task<TEntity> FindAsync(
public override async Task<IQueryable<TEntity>> GetQueryableAsync()
{
return await GetMongoQueryableAsync();
}
public override async Task<TEntity> FindAsync(
Expression<Func<TEntity, bool>> predicate,
bool includeDetails = true,
CancellationToken cancellationToken = default)
{
return await GetMongoQueryable()
return await (await GetMongoQueryableAsync(cancellationToken))
.Where(predicate)
.SingleOrDefaultAsync(GetCancellationToken(cancellationToken));
}
[Obsolete("Use GetMongoQueryableAsync method.")]
public virtual IMongoQueryable<TEntity> GetMongoQueryable()
{
return ApplyDataFilters(SessionHandle != null ? Collection.AsQueryable(SessionHandle) : Collection.AsQueryable());
return ApplyDataFilters(
SessionHandle != null
? Collection.AsQueryable(SessionHandle)
: Collection.AsQueryable()
);
}
public async Task<IMongoQueryable<TEntity>> GetMongoQueryableAsync(CancellationToken cancellationToken = default)
{
var dbContext = await GetDbContextAsync(cancellationToken);
var collection = dbContext.Collection<TEntity>();
return ApplyDataFilters(
dbContext.SessionHandle != null
? collection.AsQueryable(dbContext.SessionHandle)
: collection.AsQueryable()
);
}
protected virtual bool IsHardDeleted(TEntity entity)
{
var hardDeletedEntities = UnitOfWorkManager?.Current?.Items.GetOrDefault(UnitOfWorkItemNames.HardDeletedEntities) as HashSet<IEntity>;
@ -552,30 +627,19 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
throw new AbpDbConcurrencyException("Database operation expected to affect 1 row but actually affected 0 row. Data may have been modified or deleted since entities were loaded. This exception has been thrown on optimistic concurrency check.");
}
/// <summary>
/// IMongoQueryable<TEntity>
/// </summary>
/// <returns></returns>
[Obsolete("This method will be removed in future versions.")]
public QueryableExecutionModel GetExecutionModel()
{
return GetMongoQueryable().GetExecutionModel();
}
/// <summary>
/// IMongoQueryable<TEntity>
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[Obsolete("This method will be removed in future versions.")]
public IAsyncCursor<TEntity> ToCursor(CancellationToken cancellationToken = new CancellationToken())
{
return GetMongoQueryable().ToCursor(cancellationToken);
}
/// <summary>
/// IMongoQueryable<TEntity>
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[Obsolete("This method will be removed in future versions.")]
public Task<IAsyncCursor<TEntity>> ToCursorAsync(CancellationToken cancellationToken = new CancellationToken())
{
return GetMongoQueryable().ToCursorAsync(cancellationToken);
@ -616,16 +680,21 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
bool includeDetails = true,
CancellationToken cancellationToken = default)
{
if (SessionHandle != null)
cancellationToken = GetCancellationToken(cancellationToken);
var dbContext = await GetDbContextAsync(cancellationToken);
var collection = dbContext.Collection<TEntity>();
if (dbContext.SessionHandle != null)
{
return await Collection
.Find(SessionHandle, RepositoryFilterer.CreateEntityFilter(id, true))
.FirstOrDefaultAsync(GetCancellationToken(cancellationToken));
return await collection
.Find(dbContext.SessionHandle, RepositoryFilterer.CreateEntityFilter(id, true))
.FirstOrDefaultAsync(cancellationToken);
}
return await Collection
return await collection
.Find(RepositoryFilterer.CreateEntityFilter(id, true))
.FirstOrDefaultAsync(GetCancellationToken(cancellationToken));
.FirstOrDefaultAsync(cancellationToken);
}
public virtual Task DeleteAsync(
@ -638,9 +707,11 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
public virtual async Task DeleteManyAsync([NotNull] IEnumerable<TKey> ids, bool autoSave = false, CancellationToken cancellationToken = default)
{
var entities = await GetMongoQueryable()
cancellationToken = GetCancellationToken(cancellationToken);
var entities = await (await GetMongoQueryableAsync(cancellationToken))
.Where(x => ids.Contains(x.Id))
.ToListAsync(GetCancellationToken(cancellationToken));
.ToListAsync(cancellationToken);
await DeleteManyAsync(entities, autoSave, cancellationToken);
}

24
framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDbCoreRepositoryExtensions.cs

@ -1,4 +1,5 @@
using System;
using System.Threading.Tasks;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using Volo.Abp.Domain.Entities;
@ -8,24 +9,45 @@ namespace Volo.Abp.Domain.Repositories
{
public static class MongoDbCoreRepositoryExtensions
{
[Obsolete("Use GetDatabaseAsync method.")]
public static IMongoDatabase GetDatabase<TEntity, TKey>(this IBasicRepository<TEntity, TKey> repository)
where TEntity : class, IEntity<TKey>
{
return repository.ToMongoDbRepository().Database;
}
public static Task<IMongoDatabase> GetDatabaseAsync<TEntity, TKey>(this IBasicRepository<TEntity, TKey> repository)
where TEntity : class, IEntity<TKey>
{
return repository.ToMongoDbRepository().GetDatabaseAsync();
}
[Obsolete("Use GetCollection method.")]
public static IMongoCollection<TEntity> GetCollection<TEntity, TKey>(this IBasicRepository<TEntity, TKey> repository)
where TEntity : class, IEntity<TKey>
{
return repository.ToMongoDbRepository().Collection;
}
public static Task<IMongoCollection<TEntity>> GetCollectionAsync<TEntity, TKey>(this IBasicRepository<TEntity, TKey> repository)
where TEntity : class, IEntity<TKey>
{
return repository.ToMongoDbRepository().GetCollectionAsync();
}
[Obsolete("Use GetMongoQueryableAsync method.")]
public static IMongoQueryable<TEntity> GetMongoQueryable<TEntity, TKey>(this IBasicRepository<TEntity, TKey> repository)
where TEntity : class, IEntity<TKey>
{
return repository.ToMongoDbRepository().GetMongoQueryable();
}
public static Task<IMongoQueryable<TEntity>> GetMongoQueryableAsync<TEntity, TKey>(this IBasicRepository<TEntity, TKey> repository)
where TEntity : class, IEntity<TKey>
{
return repository.ToMongoDbRepository().GetMongoQueryableAsync();
}
public static IMongoDbRepository<TEntity, TKey> ToMongoDbRepository<TEntity, TKey>(this IBasicRepository<TEntity, TKey> repository)
where TEntity : class, IEntity<TKey>
{
@ -38,4 +60,4 @@ namespace Volo.Abp.Domain.Repositories
return mongoDbRepository;
}
}
}
}

13
framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/IMongoDbContextProvider.cs

@ -1,8 +1,15 @@
namespace Volo.Abp.MongoDB
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Volo.Abp.MongoDB
{
public interface IMongoDbContextProvider<out TMongoDbContext>
public interface IMongoDbContextProvider<TMongoDbContext>
where TMongoDbContext : IAbpMongoDbContext
{
[Obsolete("Use CreateDbContextAsync")]
TMongoDbContext GetDbContext();
Task<TMongoDbContext> GetDbContextAsync(CancellationToken cancellationToken = default);
}
}
}

2
framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/MongoDbAsyncQueryableProvider.cs

@ -12,7 +12,7 @@ using Volo.Abp.DynamicProxy;
namespace Volo.Abp.MongoDB
{
public class MongoDbAsyncQueryableProvider : IAsyncQueryableProvider, ITransientDependency
public class MongoDbAsyncQueryableProvider : IAsyncQueryableProvider, ISingletonDependency
{
public bool CanExecute<T>(IQueryable<T> queryable)
{

133
framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs

@ -1,28 +1,48 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using MongoDB.Bson;
using MongoDB.Driver;
using Volo.Abp.Data;
using Volo.Abp.MongoDB;
using Volo.Abp.Threading;
namespace Volo.Abp.Uow.MongoDB
{
public class UnitOfWorkMongoDbContextProvider<TMongoDbContext> : IMongoDbContextProvider<TMongoDbContext>
where TMongoDbContext : IAbpMongoDbContext
{
public ILogger<UnitOfWorkMongoDbContextProvider<TMongoDbContext>> Logger { get; set; }
private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly IConnectionStringResolver _connectionStringResolver;
private readonly ICancellationTokenProvider _cancellationTokenProvider;
public UnitOfWorkMongoDbContextProvider(
IUnitOfWorkManager unitOfWorkManager,
IConnectionStringResolver connectionStringResolver)
IConnectionStringResolver connectionStringResolver,
ICancellationTokenProvider cancellationTokenProvider)
{
_unitOfWorkManager = unitOfWorkManager;
_connectionStringResolver = connectionStringResolver;
_cancellationTokenProvider = cancellationTokenProvider;
Logger = NullLogger<UnitOfWorkMongoDbContextProvider<TMongoDbContext>>.Instance;
}
[Obsolete("Use CreateDbContextAsync")]
public TMongoDbContext GetDbContext()
{
Logger.LogWarning(
"UnitOfWorkDbContextProvider.GetDbContext is deprecated. Use GetDbContextAsync instead! " +
"You are probably using LINQ (LINQ extensions) directly on a repository. In this case, use repository.GetQueryableAsync() method " +
"to obtain an IQueryable<T> instance and use LINQ (LINQ extensions) on this object. "
);
Logger.LogWarning(Environment.StackTrace.Truncate(2048));
var unitOfWork = _unitOfWorkManager.Current;
if (unitOfWork == null)
{
@ -48,6 +68,46 @@ namespace Volo.Abp.Uow.MongoDB
return ((MongoDbDatabaseApi<TMongoDbContext>) databaseApi).DbContext;
}
public async Task<TMongoDbContext> GetDbContextAsync(CancellationToken cancellationToken = default)
{
var unitOfWork = _unitOfWorkManager.Current;
if (unitOfWork == null)
{
throw new AbpException(
$"A {nameof(IMongoDatabase)} instance can only be created inside a unit of work!");
}
var connectionString = await _connectionStringResolver.ResolveAsync<TMongoDbContext>();
var dbContextKey = $"{typeof(TMongoDbContext).FullName}_{connectionString}";
var mongoUrl = new MongoUrl(connectionString);
var databaseName = mongoUrl.DatabaseName;
if (databaseName.IsNullOrWhiteSpace())
{
databaseName = ConnectionStringNameAttribute.GetConnStringName<TMongoDbContext>();
}
//TODO: Create only single MongoDbClient per connection string in an application (extract MongoClientCache for example).
var databaseApi = unitOfWork.FindDatabaseApi(dbContextKey);
if (databaseApi == null)
{
databaseApi = new MongoDbDatabaseApi<TMongoDbContext>(
await CreateDbContextAsync(
unitOfWork,
mongoUrl,
databaseName,
cancellationToken
)
);
unitOfWork.AddDatabaseApi(dbContextKey, databaseApi);
}
return ((MongoDbDatabaseApi<TMongoDbContext>) databaseApi).DbContext;
}
[Obsolete("Use CreateDbContextAsync")]
private TMongoDbContext CreateDbContext(IUnitOfWork unitOfWork, MongoUrl mongoUrl, string databaseName)
{
var client = new MongoClient(mongoUrl);
@ -64,7 +124,34 @@ namespace Volo.Abp.Uow.MongoDB
return dbContext;
}
public TMongoDbContext CreateDbContextWithTransaction(
private async Task<TMongoDbContext> CreateDbContextAsync(
IUnitOfWork unitOfWork,
MongoUrl mongoUrl,
string databaseName,
CancellationToken cancellationToken = default)
{
var client = new MongoClient(mongoUrl);
var database = client.GetDatabase(databaseName);
if (unitOfWork.Options.IsTransactional)
{
return await CreateDbContextWithTransactionAsync(
unitOfWork,
mongoUrl,
client,
database,
cancellationToken
);
}
var dbContext = unitOfWork.ServiceProvider.GetRequiredService<TMongoDbContext>();
dbContext.ToAbpMongoDbContext().InitializeDatabase(database, client, null);
return dbContext;
}
[Obsolete("Use CreateDbContextWithTransactionAsync")]
private TMongoDbContext CreateDbContextWithTransaction(
IUnitOfWork unitOfWork,
MongoUrl url,
MongoClient client,
@ -99,5 +186,47 @@ namespace Volo.Abp.Uow.MongoDB
return dbContext;
}
private async Task<TMongoDbContext> CreateDbContextWithTransactionAsync(
IUnitOfWork unitOfWork,
MongoUrl url,
MongoClient client,
IMongoDatabase database,
CancellationToken cancellationToken = default)
{
var transactionApiKey = $"MongoDb_{url}";
var activeTransaction = unitOfWork.FindTransactionApi(transactionApiKey) as MongoDbTransactionApi;
var dbContext = unitOfWork.ServiceProvider.GetRequiredService<TMongoDbContext>();
if (activeTransaction?.SessionHandle == null)
{
var session = await client.StartSessionAsync(cancellationToken: GetCancellationToken(cancellationToken));
if (unitOfWork.Options.Timeout.HasValue)
{
session.AdvanceOperationTime(new BsonTimestamp(unitOfWork.Options.Timeout.Value));
}
session.StartTransaction();
unitOfWork.AddTransactionApi(
transactionApiKey,
new MongoDbTransactionApi(session)
);
dbContext.ToAbpMongoDbContext().InitializeDatabase(database, client, session);
}
else
{
dbContext.ToAbpMongoDbContext().InitializeDatabase(database, client, activeTransaction.SessionHandle);
}
return dbContext;
}
protected virtual CancellationToken GetCancellationToken(CancellationToken preferredValue = default)
{
return _cancellationTokenProvider.FallbackToProvider(preferredValue);
}
}
}

4
framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ITenantStore.cs

@ -9,8 +9,10 @@ namespace Volo.Abp.MultiTenancy
Task<TenantConfiguration> FindAsync(Guid id);
[Obsolete("Use FindAsync method.")]
TenantConfiguration Find(string name);
[Obsolete("Use FindAsync method.")]
TenantConfiguration Find(Guid id);
}
}
}

53
framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/MultiTenantConnectionStringResolver.cs

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.Data;
@ -23,6 +24,58 @@ namespace Volo.Abp.MultiTenancy
_serviceProvider = serviceProvider;
}
public override async Task<string> ResolveAsync(string connectionStringName = null)
{
//No current tenant, fallback to default logic
if (_currentTenant.Id == null)
{
return await base.ResolveAsync(connectionStringName);
}
using (var serviceScope = _serviceProvider.CreateScope())
{
var tenantStore = serviceScope
.ServiceProvider
.GetRequiredService<ITenantStore>();
var tenant = await tenantStore.FindAsync(_currentTenant.Id.Value);
if (tenant?.ConnectionStrings == null)
{
return await base.ResolveAsync(connectionStringName);
}
//Requesting default connection string
if (connectionStringName == null)
{
return tenant.ConnectionStrings.Default ??
Options.ConnectionStrings.Default;
}
//Requesting specific connection string
var connString = tenant.ConnectionStrings.GetOrDefault(connectionStringName);
if (connString != null)
{
return connString;
}
/* Requested a specific connection string, but it's not specified for the tenant.
* - If it's specified in options, use it.
* - If not, use tenant's default conn string.
*/
var connStringInOptions = Options.ConnectionStrings.GetOrDefault(connectionStringName);
if (connStringInOptions != null)
{
return connStringInOptions;
}
return tenant.ConnectionStrings.Default ??
Options.ConnectionStrings.Default;
}
}
[Obsolete("Use ResolveAsync method.")]
public override string Resolve(string connectionStringName = null)
{
//No current tenant, fallback to default logic

2
framework/src/Volo.Abp.Threading/Volo/Abp/Linq/AsyncQueryableExecuter.cs

@ -8,7 +8,7 @@ using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Linq
{
public class AsyncQueryableExecuter : IAsyncQueryableExecuter, ITransientDependency
public class AsyncQueryableExecuter : IAsyncQueryableExecuter, ISingletonDependency
{
protected IEnumerable<IAsyncQueryableProvider> Providers { get; }

7
framework/src/Volo.Abp.Uow/Volo/Abp/Uow/IUnitOfWorkTransactionBehaviourProvider.cs

@ -0,0 +1,7 @@
namespace Volo.Abp.Uow
{
public interface IUnitOfWorkTransactionBehaviourProvider
{
bool? IsTransactional { get; }
}
}

9
framework/src/Volo.Abp.Uow/Volo/Abp/Uow/NullUnitOfWorkTransactionBehaviourProvider.cs

@ -0,0 +1,9 @@
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.Uow
{
public class NullUnitOfWorkTransactionBehaviourProvider : IUnitOfWorkTransactionBehaviourProvider, ISingletonDependency
{
public bool? IsTransactional => null;
}
}

4
framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWork.cs

@ -11,6 +11,8 @@ namespace Volo.Abp.Uow
{
public class UnitOfWork : IUnitOfWork, ITransientDependency
{
public const string UnitOfWorkReservationName = "_AbpActionUnitOfWork";
public Guid Id { get; } = Guid.NewGuid();
public IAbpUnitOfWorkOptions Options { get; private set; }
@ -302,7 +304,7 @@ namespace Volo.Abp.Uow
}
}
}
protected virtual async Task CommitTransactionsAsync()
{
foreach (var transaction in GetAllActiveTransactionApis())

4
framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkFailedEventArgs.cs

@ -9,8 +9,8 @@ namespace Volo.Abp.Uow
public class UnitOfWorkFailedEventArgs : UnitOfWorkEventArgs
{
/// <summary>
/// Exception that caused failure. This is set only if an error occurred during <see cref="IUnitOfWork.Complete"/>.
/// Can be null if there is no exception, but <see cref="IUnitOfWork.Complete"/> is not called.
/// Exception that caused failure. This is set only if an error occurred during <see cref="IUnitOfWork.CompleteAsync"/>.
/// Can be null if there is no exception, but <see cref="IUnitOfWork.CompleteAsync"/> is not called.
/// Can be null if another exception occurred during the UOW.
/// </summary>
[CanBeNull]

23
framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkInterceptor.cs

@ -10,15 +10,20 @@ namespace Volo.Abp.Uow
public class UnitOfWorkInterceptor : AbpInterceptor, ITransientDependency
{
private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly IUnitOfWorkTransactionBehaviourProvider _transactionBehaviourProvider;
private readonly AbpUnitOfWorkDefaultOptions _defaultOptions;
public UnitOfWorkInterceptor(IUnitOfWorkManager unitOfWorkManager, IOptions<AbpUnitOfWorkDefaultOptions> options)
public UnitOfWorkInterceptor(
IUnitOfWorkManager unitOfWorkManager,
IOptions<AbpUnitOfWorkDefaultOptions> options,
IUnitOfWorkTransactionBehaviourProvider transactionBehaviourProvider)
{
_unitOfWorkManager = unitOfWorkManager;
_transactionBehaviourProvider = transactionBehaviourProvider;
_defaultOptions = options.Value;
}
public async override Task InterceptAsync(IAbpMethodInvocation invocation)
public override async Task InterceptAsync(IAbpMethodInvocation invocation)
{
if (!UnitOfWorkHelper.IsUnitOfWorkMethod(invocation.Method, out var unitOfWorkAttribute))
{
@ -26,7 +31,16 @@ namespace Volo.Abp.Uow
return;
}
using (var uow = _unitOfWorkManager.Begin(CreateOptions(invocation, unitOfWorkAttribute)))
var options = CreateOptions(invocation, unitOfWorkAttribute);
//Trying to begin a reserved UOW by AbpUnitOfWorkMiddleware
if (_unitOfWorkManager.TryBeginReserved(UnitOfWork.UnitOfWorkReservationName, options))
{
await invocation.ProceedAsync();
return;
}
using (var uow = _unitOfWorkManager.Begin(options))
{
await invocation.ProceedAsync();
await uow.CompleteAsync();
@ -42,7 +56,8 @@ namespace Volo.Abp.Uow
if (unitOfWorkAttribute?.IsTransactional == null)
{
options.IsTransactional = _defaultOptions.CalculateIsTransactional(
autoValue: !invocation.Method.Name.StartsWith("Get", StringComparison.InvariantCultureIgnoreCase)
autoValue: _transactionBehaviourProvider.IsTransactional
?? !invocation.Method.Name.StartsWith("Get", StringComparison.InvariantCultureIgnoreCase)
);
}

6
framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/Auditing_Tests.cs

@ -54,13 +54,13 @@ namespace Volo.Abp.Auditing
public class MyAuditedObject1 : IMyAuditedObject
{
public async virtual Task<ResultObject> DoItAsync(InputObject inputObject)
public virtual Task<ResultObject> DoItAsync(InputObject inputObject)
{
return new ResultObject
return Task.FromResult(new ResultObject
{
Value1 = inputObject.Value1 + "-result",
Value2 = inputObject.Value2 + 1
};
});
}
}

4
framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AbpAutoMapperModule_Basic_Tests.cs

@ -38,12 +38,12 @@ namespace Volo.Abp.AutoMapper
}
//[Fact] TODO: Disabled because of https://github.com/AutoMapper/AutoMapper/pull/2379#issuecomment-355899664
public void Should_Not_Map_Objects_With_AutoMap_Attributes()
/*public void Should_Not_Map_Objects_With_AutoMap_Attributes()
{
Assert.ThrowsAny<Exception>(() =>
{
_objectMapper.Map<MyEntity, MyNotMappedDto>(new MyEntity {Number = 42});
});
}
}*/
}
}

15
framework/test/Volo.Abp.Dapper.Tests/Volo/Abp/Dapper/Repositories/PersonDapperRepository.cs

@ -17,14 +17,19 @@ namespace Volo.Abp.Dapper.Repositories
public virtual async Task<List<string>> GetAllPersonNames()
{
return (await DbConnection.QueryAsync<string>("select Name from People", transaction: DbTransaction))
.ToList();
return (await (await GetDbConnectionAsync())
.QueryAsync<string>(
"select Name from People",
transaction: await GetDbTransactionAsync()
)
).ToList();
}
public virtual async Task<int> UpdatePersonNames(string name)
{
return await DbConnection.ExecuteAsync("update People set Name = @NewName", new { NewName = name },
DbTransaction);
return await (await GetDbConnectionAsync())
.ExecuteAsync("update People set Name = @NewName", new {NewName = name},
await GetDbTransactionAsync());
}
}
}
}

15
framework/test/Volo.Abp.Data.Tests/Volo/Abp/Data/ConnectionStringResolver_Tests.cs

@ -1,4 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using Volo.Abp.Modularity;
using Volo.Abp.Testing;
@ -21,21 +22,21 @@ namespace Volo.Abp.Data
}
[Fact]
public void Should_Get_Default_ConnString_By_Default()
public async Task Should_Get_Default_ConnString_By_Default()
{
_connectionStringResolver.Resolve().ShouldBe(DefaultConnString);
(await _connectionStringResolver.ResolveAsync()).ShouldBe(DefaultConnString);
}
[Fact]
public void Should_Get_Specific_ConnString_IfDefined()
public async Task Should_Get_Specific_ConnString_IfDefined()
{
_connectionStringResolver.Resolve(Database1Name).ShouldBe(Database1ConnString);
(await _connectionStringResolver.ResolveAsync(Database1Name)).ShouldBe(Database1ConnString);
}
[Fact]
public void Should_Get_Default_ConnString_If_Not_Specified()
public async Task Should_Get_Default_ConnString_If_Not_Specified()
{
_connectionStringResolver.Resolve(Database2Name).ShouldBe(DefaultConnString);
(await _connectionStringResolver.ResolveAsync(Database2Name)).ShouldBe(DefaultConnString);
}
[DependsOn(typeof(AbpDataModule))]

6
framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Repositories/RepositoryRegistration_Tests.cs

@ -242,11 +242,17 @@ namespace Volo.Abp.Domain.Repositories
where TEntity : class, IEntity
{
[Obsolete("Use GetQueryableAsync method.")]
protected override IQueryable<TEntity> GetQueryable()
{
throw new NotImplementedException();
}
public override Task<IQueryable<TEntity>> GetQueryableAsync()
{
throw new NotImplementedException();
}
public override Task<TEntity> FindAsync(Expression<Func<TEntity, bool>> predicate, bool includeDetails = true, CancellationToken cancellationToken = default)
{
throw new NotImplementedException();

8
framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/DbContext_Replace_Tests.cs

@ -26,12 +26,12 @@ namespace Volo.Abp.EntityFrameworkCore
{
(ServiceProvider.GetRequiredService<IThirdDbContext>() is TestAppDbContext).ShouldBeTrue();
using (_unitOfWorkManager.Begin())
using (var uow = _unitOfWorkManager.Begin())
{
(_dummyRepository.GetDbContext() is IThirdDbContext).ShouldBeTrue();
(_dummyRepository.GetDbContext() is TestAppDbContext).ShouldBeTrue();
((await _dummyRepository.GetDbContextAsync()) is IThirdDbContext).ShouldBeTrue();
((await _dummyRepository.GetDbContextAsync()) is TestAppDbContext).ShouldBeTrue();
await _unitOfWorkManager.Current.CompleteAsync();
await uow.CompleteAsync();
}
}
}

6
framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Domain/ExtraProperties_Tests.cs

@ -44,15 +44,13 @@ namespace Volo.Abp.EntityFrameworkCore.Domain
[Fact]
public async Task An_Extra_Property_Configured_As_Extension2()
{
await WithUnitOfWorkAsync(() =>
await WithUnitOfWorkAsync(async () =>
{
var entityEntry = CityRepository.GetDbContext().Attach(new City(Guid.NewGuid(), "NewYork"));
var entityEntry = (await CityRepository.GetDbContextAsync()).Attach(new City(Guid.NewGuid(), "NewYork"));
var indexes = entityEntry.Metadata.GetIndexes().ToList();
indexes.ShouldNotBeEmpty();
indexes.ShouldContain(x => x.IsUnique);
return Task.CompletedTask;
});
}
}
}

4
framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/CityRepository.cs

@ -11,7 +11,7 @@ namespace Volo.Abp.TestApp.EntityFrameworkCore
{
public class CityRepository : EfCoreRepository<TestAppDbContext, City, Guid>, ICityRepository
{
public CityRepository(IDbContextProvider<TestAppDbContext> dbContextProvider)
public CityRepository(IDbContextProvider<TestAppDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
@ -24,7 +24,7 @@ namespace Volo.Abp.TestApp.EntityFrameworkCore
public async Task<List<Person>> GetPeopleInTheCityAsync(string cityName)
{
var city = await FindByNameAsync(cityName);
return await DbContext.People.Where(p => p.CityId == city.Id).ToListAsync();
return await (await GetDbContextAsync()).People.Where(p => p.CityId == city.Id).ToListAsync();
}
}
}

4
framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/PersonRepository.cs

@ -18,7 +18,7 @@ namespace Volo.Abp.TestApp.EntityFrameworkCore
public async Task<PersonView> GetViewAsync(string name)
{
return await DbContext.PersonView.Where(x => x.Name == name).FirstOrDefaultAsync();
return await (await GetDbContextAsync()).PersonView.Where(x => x.Name == name).FirstOrDefaultAsync();
}
}
}
}

8
framework/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/TestApp/MemoryDb/CityRepository.cs

@ -10,21 +10,21 @@ namespace Volo.Abp.TestApp.MemoryDb
{
public class CityRepository : MemoryDbRepository<TestAppMemoryDbContext, City, Guid>, ICityRepository
{
public CityRepository(IMemoryDatabaseProvider<TestAppMemoryDbContext> databaseProvider)
public CityRepository(IMemoryDatabaseProvider<TestAppMemoryDbContext> databaseProvider)
: base(databaseProvider)
{
}
public Task<City> FindByNameAsync(string name)
public async Task<City> FindByNameAsync(string name)
{
return Task.FromResult(Collection.FirstOrDefault(c => c.Name == name));
return (await GetCollectionAsync()).FirstOrDefault(c => c.Name == name);
}
public async Task<List<Person>> GetPeopleInTheCityAsync(string cityName)
{
var city = await FindByNameAsync(cityName);
return Database.Collection<Person>().Where(p => p.CityId == city.Id).ToList();
return (await GetDatabaseAsync()).Collection<Person>().Where(p => p.CityId == city.Id).ToList();
}
}
}

4
framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/MongoDbAsyncQueryableProvider_Tests.cs

@ -25,10 +25,10 @@ namespace Volo.Abp.MongoDB.Repositories
}
[Fact]
public void CanExecute()
public async Task CanExecuteAsync()
{
_mongoDbAsyncQueryableProvider.CanExecute(_personRepository).ShouldBeTrue();
_mongoDbAsyncQueryableProvider.CanExecute(_personRepository.WithDetails()).ShouldBeTrue();
_mongoDbAsyncQueryableProvider.CanExecute(await _personRepository.WithDetailsAsync()).ShouldBeTrue();
}
[Fact]

4
framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/TestApp/MongoDb/CityRepository.cs

@ -19,13 +19,13 @@ namespace Volo.Abp.TestApp.MongoDB
public async Task<City> FindByNameAsync(string name)
{
return await (await Collection.FindAsync(c => c.Name == name)).FirstOrDefaultAsync();
return await (await (await GetCollectionAsync()).FindAsync(c => c.Name == name)).FirstOrDefaultAsync();
}
public async Task<List<Person>> GetPeopleInTheCityAsync(string cityName)
{
var city = await FindByNameAsync(cityName);
return await DbContext.People.AsQueryable().Where(p => p.CityId == city.Id).ToListAsync();
return await (await GetDbContextAsync()).People.AsQueryable().Where(p => p.CityId == city.Id).ToListAsync();
}
}
}

21
framework/test/Volo.Abp.MultiTenancy.Tests/Volo/Abp/Data/MultiTenancy/MultiTenantConnectionStringResolver_Tests.cs

@ -1,4 +1,5 @@
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using Volo.Abp.MultiTenancy;
@ -49,28 +50,28 @@ namespace Volo.Abp.Data.MultiTenancy
}
[Fact]
public void All_Tests()
public async Task All_Tests()
{
//No tenant in current context
_connectionResolver.Resolve().ShouldBe("default-value");
_connectionResolver.Resolve("db1").ShouldBe("db1-default-value");
(await _connectionResolver.ResolveAsync()).ShouldBe("default-value");
(await _connectionResolver.ResolveAsync("db1")).ShouldBe("db1-default-value");
//Overrided connection strings for tenant1
//Overriden connection strings for tenant1
using (_currentTenant.Change(_tenant1Id))
{
_connectionResolver.Resolve().ShouldBe("tenant1-default-value");
_connectionResolver.Resolve("db1").ShouldBe("tenant1-db1-value");
(await _connectionResolver.ResolveAsync()).ShouldBe("tenant1-default-value");
(await _connectionResolver.ResolveAsync("db1")).ShouldBe("tenant1-db1-value");
}
//No tenant in current context
_connectionResolver.Resolve().ShouldBe("default-value");
_connectionResolver.Resolve("db1").ShouldBe("db1-default-value");
(await _connectionResolver.ResolveAsync()).ShouldBe("default-value");
(await _connectionResolver.ResolveAsync("db1")).ShouldBe("db1-default-value");
//Undefined connection strings for tenant2
using (_currentTenant.Change(_tenant2Id))
{
_connectionResolver.Resolve().ShouldBe("default-value");
_connectionResolver.Resolve("db1").ShouldBe("db1-default-value");
(await _connectionResolver.ResolveAsync()).ShouldBe("default-value");
(await _connectionResolver.ResolveAsync("db1")).ShouldBe("db1-default-value");
}
}
}

10
framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/Repository_Queryable_Tests.cs

@ -44,24 +44,22 @@ namespace Volo.Abp.TestApp.Testing
[Fact]
public async Task WithDetails()
{
await WithUnitOfWorkAsync(() =>
await WithUnitOfWorkAsync(async () =>
{
var person = PersonRepository.WithDetails().Single(p => p.Id == TestDataBuilder.UserDouglasId);
var person = (await PersonRepository.WithDetailsAsync()).Single(p => p.Id == TestDataBuilder.UserDouglasId);
person.Name.ShouldBe("Douglas");
person.Phones.Count.ShouldBe(2);
return Task.CompletedTask;
});
}
[Fact]
public async Task WithDetails_Explicit()
{
await WithUnitOfWorkAsync(() =>
await WithUnitOfWorkAsync(async () =>
{
var person = PersonRepository.WithDetails(p => p.Phones).Single(p => p.Id == TestDataBuilder.UserDouglasId);
var person = (await PersonRepository.WithDetailsAsync(p => p.Phones)).Single(p => p.Id == TestDataBuilder.UserDouglasId);
person.Name.ShouldBe("Douglas");
person.Phones.Count.ShouldBe(2);
return Task.CompletedTask;
});
}
}

34
framework/test/Volo.Abp.Uow.Tests/Volo/Abp/Uow/UnitOfWork_Events_Tests.cs

@ -26,7 +26,7 @@ namespace Volo.Abp.Uow
{
uow.OnCompleted(() =>
{
completed = true;
completed = true;
return Task.CompletedTask;
});
@ -50,7 +50,12 @@ namespace Volo.Abp.Uow
{
using (var childUow = _unitOfWorkManager.Begin())
{
childUow.OnCompleted(async () => completed = true);
childUow.OnCompleted(() =>
{
completed = true;
return Task.CompletedTask;
});
uow.Disposed += (sender, args) => disposed = true;
await childUow.CompleteAsync();
@ -80,9 +85,14 @@ namespace Volo.Abp.Uow
using (var uow = _unitOfWorkManager.Begin())
{
uow.OnCompleted(async () => completed = true);
uow.Failed += (sender, args) => failed = true;
uow.Disposed += (sender, args) => disposed = true;
uow.OnCompleted(() =>
{
completed = true;
return Task.CompletedTask;
});
uow.Failed += (_, _) => failed = true;
uow.Disposed += (_, _) => disposed = true;
}
completed.ShouldBeFalse();
@ -101,7 +111,12 @@ namespace Volo.Abp.Uow
{
using (var uow = _unitOfWorkManager.Begin())
{
uow.OnCompleted(async () => completed = true);
uow.OnCompleted(() =>
{
completed = true;
return Task.CompletedTask;
});
uow.Failed += (sender, args) => failed = true;
uow.Disposed += (sender, args) => disposed = true;
@ -125,7 +140,12 @@ namespace Volo.Abp.Uow
using (var uow = _unitOfWorkManager.Begin())
{
uow.OnCompleted(async () => completed = true);
uow.OnCompleted(() =>
{
completed = true;
return Task.CompletedTask;
});
uow.Failed += (sender, args) => { failed = true; args.IsRolledback.ShouldBeTrue(); };
uow.Disposed += (sender, args) => disposed = true;

52
modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs

@ -39,7 +39,7 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var query = GetListQuery(
var query = await GetListQueryAsync(
startTime,
endTime,
httpMethod,
@ -75,7 +75,7 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore
HttpStatusCode? httpStatusCode = null,
CancellationToken cancellationToken = default)
{
var query = GetListQuery(
var query = await GetListQueryAsync(
startTime,
endTime,
httpMethod,
@ -94,7 +94,7 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore
return totalCount;
}
protected virtual IQueryable<AuditLog> GetListQuery(
protected virtual async Task<IQueryable<AuditLog>> GetListQueryAsync(
DateTime? startTime = null,
DateTime? endTime = null,
string httpMethod = null,
@ -109,7 +109,7 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore
bool includeDetails = false)
{
var nHttpStatusCode = (int?) httpStatusCode;
return DbSet.AsNoTracking()
return (await GetDbSetAsync()).AsNoTracking()
.IncludeDetails(includeDetails)
.WhereIf(startTime.HasValue, auditLog => auditLog.ExecutionTime >= startTime)
.WhereIf(endTime.HasValue, auditLog => auditLog.ExecutionTime <= endTime)
@ -127,7 +127,7 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore
public virtual async Task<Dictionary<DateTime, double>> GetAverageExecutionDurationPerDayAsync(DateTime startDate, DateTime endDate)
{
var result = await DbSet.AsNoTracking()
var result = await (await GetDbSetAsync()).AsNoTracking()
.Where(a => a.ExecutionTime < endDate.AddDays(1) && a.ExecutionTime > startDate)
.OrderBy(t => t.ExecutionTime)
.GroupBy(t => new { t.ExecutionTime.Date })
@ -137,14 +137,20 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore
return result.ToDictionary(element => element.Day.ClearTime(), element => element.avgExecutionTime);
}
[Obsolete("Use WithDetailsAsync method.")]
public override IQueryable<AuditLog> WithDetails()
{
return GetQueryable().IncludeDetails();
}
public override async Task<IQueryable<AuditLog>> WithDetailsAsync()
{
return (await GetQueryableAsync()).IncludeDetails();
}
public virtual async Task<EntityChange> GetEntityChange(Guid entityChangeId)
{
var entityChange = await DbContext.Set<EntityChange>()
var entityChange = await (await GetDbContextAsync()).Set<EntityChange>()
.AsNoTracking()
.IncludeDetails()
.Where(x => x.Id == entityChangeId)
@ -172,7 +178,7 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var query = GetEntityChangeListQuery(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName, includeDetails);
var query = await GetEntityChangeListQueryAsync(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName, includeDetails);
return await query.OrderBy(sorting ?? "changeTime desc")
.PageBy(skipCount, maxResultCount)
@ -188,7 +194,7 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore
string entityTypeFullName = null,
CancellationToken cancellationToken = default)
{
var query = GetEntityChangeListQuery(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName);
var query = await GetEntityChangeListQueryAsync(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName);
var totalCount = await query.LongCountAsync(GetCancellationToken(cancellationToken));
@ -197,7 +203,7 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore
public virtual async Task<EntityChangeWithUsername> GetEntityChangeWithUsernameAsync(Guid entityChangeId)
{
var auditLog = await DbSet.AsNoTracking().IncludeDetails()
var auditLog = await (await GetDbSetAsync()).AsNoTracking().IncludeDetails()
.Where(x => x.EntityChanges.Any(y => y.Id == entityChangeId)).FirstAsync();
return new EntityChangeWithUsername()
@ -209,18 +215,20 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore
public virtual async Task<List<EntityChangeWithUsername>> GetEntityChangesWithUsernameAsync(string entityId, string entityTypeFullName)
{
var query = DbContext.Set<EntityChange>()
var dbContext = await GetDbContextAsync();
var query = dbContext.Set<EntityChange>()
.AsNoTracking()
.IncludeDetails()
.Where(x => x.EntityId == entityId && x.EntityTypeFullName == entityTypeFullName);
return await (from e in query
join auditLog in DbSet on e.AuditLogId equals auditLog.Id
select new EntityChangeWithUsername() {EntityChange = e, UserName = auditLog.UserName})
join auditLog in dbContext.AuditLogs on e.AuditLogId equals auditLog.Id
select new EntityChangeWithUsername {EntityChange = e, UserName = auditLog.UserName})
.OrderByDescending(x => x.EntityChange.ChangeTime).ToListAsync();
}
protected virtual IQueryable<EntityChange> GetEntityChangeListQuery(
protected virtual async Task<IQueryable<EntityChange>> GetEntityChangeListQueryAsync(
Guid? auditLogId = null,
DateTime? startTime = null,
DateTime? endTime = null,
@ -229,14 +237,16 @@ namespace Volo.Abp.AuditLogging.EntityFrameworkCore
string entityTypeFullName = null,
bool includeDetails = false)
{
return DbContext.Set<EntityChange>().AsNoTracking().IncludeDetails(includeDetails)
.WhereIf(auditLogId.HasValue, e => e.AuditLogId == auditLogId)
.WhereIf(startTime.HasValue, e => e.ChangeTime >= startTime)
.WhereIf(endTime.HasValue, e => e.ChangeTime <= endTime)
.WhereIf(changeType.HasValue, e => e.ChangeType == changeType)
.WhereIf(!string.IsNullOrWhiteSpace(entityId), e => e.EntityId == entityId)
.WhereIf(!string.IsNullOrWhiteSpace(entityTypeFullName),
e => e.EntityTypeFullName.Contains(entityTypeFullName));
return (await GetDbContextAsync())
.Set<EntityChange>()
.AsNoTracking()
.IncludeDetails(includeDetails)
.WhereIf(auditLogId.HasValue, e => e.AuditLogId == auditLogId)
.WhereIf(startTime.HasValue, e => e.ChangeTime >= startTime)
.WhereIf(endTime.HasValue, e => e.ChangeTime <= endTime)
.WhereIf(changeType.HasValue, e => e.ChangeType == changeType)
.WhereIf(!string.IsNullOrWhiteSpace(entityId), e => e.EntityId == entityId)
.WhereIf(!string.IsNullOrWhiteSpace(entityTypeFullName), e => e.EntityTypeFullName.Contains(entityTypeFullName));
}
}
}

25
modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs

@ -40,7 +40,7 @@ namespace Volo.Abp.AuditLogging.MongoDB
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var query = GetListQuery(
var query = await GetListQueryAsync(
startTime,
endTime,
httpMethod,
@ -74,7 +74,7 @@ namespace Volo.Abp.AuditLogging.MongoDB
HttpStatusCode? httpStatusCode = null,
CancellationToken cancellationToken = default)
{
var query = GetListQuery(
var query = await GetListQueryAsync(
startTime,
endTime,
httpMethod,
@ -94,7 +94,7 @@ namespace Volo.Abp.AuditLogging.MongoDB
return count;
}
protected virtual IQueryable<AuditLog> GetListQuery(
protected virtual async Task<IQueryable<AuditLog>> GetListQueryAsync(
DateTime? startTime = null,
DateTime? endTime = null,
string httpMethod = null,
@ -108,7 +108,7 @@ namespace Volo.Abp.AuditLogging.MongoDB
HttpStatusCode? httpStatusCode = null,
bool includeDetails = false)
{
return GetMongoQueryable()
return (await GetMongoQueryableAsync())
.WhereIf(startTime.HasValue, auditLog => auditLog.ExecutionTime >= startTime)
.WhereIf(endTime.HasValue, auditLog => auditLog.ExecutionTime <= endTime)
.WhereIf(hasException.HasValue && hasException.Value, auditLog => auditLog.Exceptions != null && auditLog.Exceptions != "")
@ -126,7 +126,7 @@ namespace Volo.Abp.AuditLogging.MongoDB
public virtual async Task<Dictionary<DateTime, double>> GetAverageExecutionDurationPerDayAsync(DateTime startDate, DateTime endDate)
{
var result = await GetMongoQueryable()
var result = await (await GetMongoQueryableAsync())
.Where(a => a.ExecutionTime < endDate.AddDays(1) && a.ExecutionTime > startDate)
.OrderBy(t => t.ExecutionTime)
.GroupBy(t => new
@ -143,12 +143,11 @@ namespace Volo.Abp.AuditLogging.MongoDB
public virtual async Task<EntityChange> GetEntityChange(Guid entityChangeId)
{
var entityChange = (await GetMongoQueryable()
var entityChange = (await (await GetMongoQueryableAsync())
.Where(x => x.EntityChanges.Any(y => y.Id == entityChangeId))
.OrderBy(x => x.Id)
.FirstAsync()).EntityChanges.FirstOrDefault(x => x.Id == entityChangeId);
if (entityChange == null)
{
throw new EntityNotFoundException(typeof(EntityChange));
@ -170,7 +169,7 @@ namespace Volo.Abp.AuditLogging.MongoDB
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var query = GetEntityChangeListQuery(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName);
var query = await GetEntityChangeListQueryAsync(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName);
var auditLogs = await query.As<IMongoQueryable<EntityChange>>()
.PageBy<EntityChange, IMongoQueryable<EntityChange>>(skipCount, maxResultCount)
@ -188,7 +187,7 @@ namespace Volo.Abp.AuditLogging.MongoDB
string entityTypeFullName = null,
CancellationToken cancellationToken = default)
{
var query = GetEntityChangeListQuery(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName);
var query = await GetEntityChangeListQueryAsync(auditLogId, startTime, endTime, changeType, entityId, entityTypeFullName);
var count = await query.As<IMongoQueryable<EntityChange>>().LongCountAsync(GetCancellationToken(cancellationToken));
@ -197,7 +196,7 @@ namespace Volo.Abp.AuditLogging.MongoDB
public virtual async Task<EntityChangeWithUsername> GetEntityChangeWithUsernameAsync(Guid entityChangeId)
{
var auditLog = (await GetMongoQueryable()
var auditLog = (await (await GetMongoQueryableAsync())
.Where(x => x.EntityChanges.Any(y => y.Id == entityChangeId))
.FirstAsync());
@ -210,7 +209,7 @@ namespace Volo.Abp.AuditLogging.MongoDB
public virtual async Task<List<EntityChangeWithUsername>> GetEntityChangesWithUsernameAsync(string entityId, string entityTypeFullName)
{
var auditLogs = await GetMongoQueryable()
var auditLogs = await (await GetMongoQueryableAsync())
.Where(x => x.EntityChanges.Any(y => y.EntityId == entityId && y.EntityTypeFullName == entityTypeFullName))
.As<IMongoQueryable<AuditLog>>()
.OrderByDescending(x => x.ExecutionTime)
@ -224,7 +223,7 @@ namespace Volo.Abp.AuditLogging.MongoDB
{EntityChange = x, UserName = auditLogs.First(y => y.Id == x.AuditLogId).UserName}).ToList();
}
protected virtual IQueryable<EntityChange> GetEntityChangeListQuery(
protected virtual async Task<IQueryable<EntityChange>> GetEntityChangeListQueryAsync(
Guid? auditLogId = null,
DateTime? startTime = null,
DateTime? endTime = null,
@ -232,7 +231,7 @@ namespace Volo.Abp.AuditLogging.MongoDB
string entityId = null,
string entityTypeFullName = null)
{
return GetMongoQueryable()
return (await GetMongoQueryableAsync())
.SelectMany(x => x.EntityChanges)
.WhereIf(auditLogId.HasValue, e => e.Id == auditLogId)
.WhereIf(startTime.HasValue, e => e.ChangeTime >= startTime)

9
modules/background-jobs/src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo/Abp/BackgroundJobs/EntityFrameworkCore/EfCoreBackgroundJobRepository.cs

@ -15,7 +15,7 @@ namespace Volo.Abp.BackgroundJobs.EntityFrameworkCore
public EfCoreBackgroundJobRepository(
IDbContextProvider<IBackgroundJobsDbContext> dbContextProvider,
IClock clock)
IClock clock)
: base(dbContextProvider)
{
Clock = clock;
@ -23,14 +23,13 @@ namespace Volo.Abp.BackgroundJobs.EntityFrameworkCore
public virtual async Task<List<BackgroundJobRecord>> GetWaitingListAsync(int maxResultCount)
{
return await GetWaitingListQuery(maxResultCount)
.ToListAsync();
return await (await GetWaitingListQueryAsync(maxResultCount)).ToListAsync();
}
protected virtual IQueryable<BackgroundJobRecord> GetWaitingListQuery(int maxResultCount)
protected virtual async Task<IQueryable<BackgroundJobRecord>> GetWaitingListQueryAsync(int maxResultCount)
{
var now = Clock.Now;
return DbSet
return (await GetDbSetAsync())
.Where(t => !t.IsAbandoned && t.NextTryTime <= now)
.OrderByDescending(t => t.Priority)
.ThenBy(t => t.TryCount)

11
modules/background-jobs/src/Volo.Abp.BackgroundJobs.MongoDB/Volo/Abp/BackgroundJobs/MongoDB/MongoBackgroundJobRepository.cs

@ -14,8 +14,8 @@ namespace Volo.Abp.BackgroundJobs.MongoDB
protected IClock Clock { get; }
public MongoBackgroundJobRepository(
IMongoDbContextProvider<IBackgroundJobsMongoDbContext> dbContextProvider,
IClock clock)
IMongoDbContextProvider<IBackgroundJobsMongoDbContext> dbContextProvider,
IClock clock)
: base(dbContextProvider)
{
Clock = clock;
@ -23,14 +23,13 @@ namespace Volo.Abp.BackgroundJobs.MongoDB
public virtual async Task<List<BackgroundJobRecord>> GetWaitingListAsync(int maxResultCount)
{
return await GetWaitingListQuery(maxResultCount)
.ToListAsync();
return await (await GetWaitingListQuery(maxResultCount)).ToListAsync();
}
protected virtual IMongoQueryable<BackgroundJobRecord> GetWaitingListQuery(int maxResultCount)
protected virtual async Task<IMongoQueryable<BackgroundJobRecord>> GetWaitingListQuery(int maxResultCount)
{
var now = Clock.Now;
return GetMongoQueryable()
return (await GetMongoQueryableAsync())
.Where(t => !t.IsAbandoned && t.NextTryTime <= now)
.OrderByDescending(t => t.Priority)
.ThenBy(t => t.TryCount)

7
modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.EntityFrameworkCore/Volo/Abp/BlobStoring/Database/EntityFrameworkCore/EfCoreDatabaseBlobContainerRepository.cs

@ -10,14 +10,15 @@ namespace Volo.Abp.BlobStoring.Database.EntityFrameworkCore
{
public class EfCoreDatabaseBlobContainerRepository : EfCoreRepository<IBlobStoringDbContext, DatabaseBlobContainer, Guid>, IDatabaseBlobContainerRepository
{
public EfCoreDatabaseBlobContainerRepository(IDbContextProvider<IBlobStoringDbContext> dbContextProvider)
public EfCoreDatabaseBlobContainerRepository(IDbContextProvider<IBlobStoringDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
public virtual async Task<DatabaseBlobContainer> FindAsync(string name, CancellationToken cancellationToken = default)
{
return await DbSet.FirstOrDefaultAsync(x => x.Name == name, GetCancellationToken(cancellationToken));
return await (await GetDbSetAsync())
.FirstOrDefaultAsync(x => x.Name == name, GetCancellationToken(cancellationToken));
}
}
}
}

13
modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.EntityFrameworkCore/Volo/Abp/BlobStoring/Database/EntityFrameworkCore/EfCoreDatabaseBlobRepository.cs

@ -20,7 +20,8 @@ namespace Volo.Abp.BlobStoring.Database.EntityFrameworkCore
string name,
CancellationToken cancellationToken = default)
{
return await DbSet.FirstOrDefaultAsync(
return await (await GetDbSetAsync())
.FirstOrDefaultAsync(
x => x.ContainerId == containerId && x.Name == name,
GetCancellationToken(cancellationToken)
);
@ -31,9 +32,11 @@ namespace Volo.Abp.BlobStoring.Database.EntityFrameworkCore
string name,
CancellationToken cancellationToken = default)
{
return await DbSet.AnyAsync(
x => x.ContainerId == containerId && x.Name == name,
GetCancellationToken(cancellationToken));
return await (await GetDbSetAsync())
.AnyAsync(
x => x.ContainerId == containerId && x.Name == name,
GetCancellationToken(cancellationToken)
);
}
public virtual async Task<bool> DeleteAsync(
@ -54,4 +57,4 @@ namespace Volo.Abp.BlobStoring.Database.EntityFrameworkCore
return true;
}
}
}
}

30
modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.MongoDB/Volo/Abp/BlobStoring/Database/MongoDB/MongoDbDatabaseBlobRepository.cs

@ -15,35 +15,41 @@ namespace Volo.Abp.BlobStoring.Database.MongoDB
public virtual async Task<DatabaseBlob> FindAsync(Guid containerId, string name, CancellationToken cancellationToken = default)
{
return await GetMongoQueryable().FirstOrDefaultAsync(
x => x.ContainerId == containerId &&
x.Name == name,
GetCancellationToken(cancellationToken));
cancellationToken = GetCancellationToken(cancellationToken);
return await (await GetMongoQueryableAsync(cancellationToken))
.FirstOrDefaultAsync(
x => x.ContainerId == containerId && x.Name == name,
cancellationToken
);
}
public virtual async Task<bool> ExistsAsync(Guid containerId, string name, CancellationToken cancellationToken = default)
{
return await GetMongoQueryable().AnyAsync(
x => x.ContainerId == containerId &&
x.Name == name,
GetCancellationToken(cancellationToken));
cancellationToken = GetCancellationToken(cancellationToken);
return await (await GetMongoQueryableAsync(cancellationToken))
.AnyAsync(
x => x.ContainerId == containerId && x.Name == name,
cancellationToken
);
}
public virtual async Task<bool> DeleteAsync(
Guid containerId,
Guid containerId,
string name,
bool autoSave = false,
CancellationToken cancellationToken = default)
{
var blob = await FindAsync(containerId, name, cancellationToken);
if (blob == null)
{
return false;
}
await base.DeleteAsync(blob, autoSave, cancellationToken: GetCancellationToken(cancellationToken));
await base.DeleteAsync(blob, autoSave, cancellationToken);
return true;
}
}
}
}

6
modules/feature-management/src/Volo.Abp.FeatureManagement.EntityFrameworkCore/Volo/Abp/FeatureManagement/EntityFrameworkCore/EfCoreFeatureValueRepository.cs

@ -17,7 +17,7 @@ namespace Volo.Abp.FeatureManagement.EntityFrameworkCore
public virtual async Task<FeatureValue> FindAsync(string name, string providerName, string providerKey)
{
return await DbSet
return await (await GetDbSetAsync())
.OrderBy(x => x.Id)
.FirstOrDefaultAsync(
s => s.Name == name && s.ProviderName == providerName && s.ProviderKey == providerKey
@ -26,7 +26,7 @@ namespace Volo.Abp.FeatureManagement.EntityFrameworkCore
public async Task<List<FeatureValue>> FindAllAsync(string name, string providerName, string providerKey)
{
return await DbSet
return await (await GetDbSetAsync())
.Where(
s => s.Name == name && s.ProviderName == providerName && s.ProviderKey == providerKey
).ToListAsync();
@ -34,7 +34,7 @@ namespace Volo.Abp.FeatureManagement.EntityFrameworkCore
public virtual async Task<List<FeatureValue>> GetListAsync(string providerName, string providerKey)
{
return await DbSet
return await (await GetDbSetAsync())
.Where(
s => s.ProviderName == providerName && s.ProviderKey == providerKey
).ToListAsync();

6
modules/feature-management/src/Volo.Abp.FeatureManagement.MongoDB/Volo/Abp/FeatureManagement/MongoDB/MongoFeatureValueRepository.cs

@ -18,20 +18,20 @@ namespace Volo.Abp.FeatureManagement.MongoDB
public virtual async Task<FeatureValue> FindAsync(string name, string providerName, string providerKey)
{
return await GetMongoQueryable()
return await (await GetMongoQueryableAsync())
.OrderBy(x => x.Id)
.FirstOrDefaultAsync(s => s.Name == name && s.ProviderName == providerName && s.ProviderKey == providerKey);
}
public async Task<List<FeatureValue>> FindAllAsync(string name, string providerName, string providerKey)
{
return await GetMongoQueryable()
return await (await GetMongoQueryableAsync())
.Where(s => s.Name == name && s.ProviderName == providerName && s.ProviderKey == providerKey).ToListAsync();
}
public virtual async Task<List<FeatureValue>> GetListAsync(string providerName, string providerKey)
{
return await GetMongoQueryable()
return await (await GetMongoQueryableAsync())
.Where(s => s.ProviderName == providerName && s.ProviderKey == providerKey)
.ToListAsync();
}

5
modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/OrganizationUnit.cs

@ -49,12 +49,13 @@ namespace Volo.Abp.Identity
/// <summary>
/// Initializes a new instance of the <see cref="OrganizationUnit"/> class.
/// </summary>
/// <param name="tenantId">Tenant's Id or null for host.</param>
/// <param name="id">id</param>
/// <param name="displayName">Display name.</param>
/// <param name="parentId">Parent's Id or null if OU is a root.</param>
/// <param name="tenantId">Tenant's Id or null for host.</param>
public OrganizationUnit(Guid id, string displayName, Guid? parentId = null, Guid? tenantId = null)
: base(id)
{
Id = id;
TenantId = tenantId;
DisplayName = displayName;
ParentId = parentId;

29
modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EFCoreIdentitySecurityLogRepository.cs

@ -34,7 +34,9 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var query = GetListQuery(
cancellationToken = GetCancellationToken(cancellationToken);
var query = await GetListQueryAsync(
startTime,
endTime,
applicationName,
@ -43,12 +45,13 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
userId,
userName,
clientId,
correlationId
correlationId,
cancellationToken
);
return await query.OrderBy(sorting ?? nameof(IdentitySecurityLog.CreationTime) + " desc")
.PageBy(skipCount, maxResultCount)
.ToListAsync(GetCancellationToken(cancellationToken));
.ToListAsync(cancellationToken);
}
public async Task<long> GetCountAsync(
@ -63,7 +66,9 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
string correlationId = null,
CancellationToken cancellationToken = default)
{
var query = GetListQuery(
cancellationToken = GetCancellationToken(cancellationToken);
var query = await GetListQueryAsync(
startTime,
endTime,
applicationName,
@ -72,18 +77,21 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
userId,
userName,
clientId,
correlationId
correlationId,
cancellationToken
);
return await query.LongCountAsync(GetCancellationToken(cancellationToken));
return await query.LongCountAsync(cancellationToken);
}
public async Task<IdentitySecurityLog> GetByUserIdAsync(Guid id, Guid userId, bool includeDetails = false, CancellationToken cancellationToken = default)
{
return await DbSet.OrderBy(x => x.Id).FirstOrDefaultAsync(x => x.Id == id && x.UserId == userId, GetCancellationToken(cancellationToken));
return await (await GetDbSetAsync())
.OrderBy(x => x.Id)
.FirstOrDefaultAsync(x => x.Id == id && x.UserId == userId, GetCancellationToken(cancellationToken));
}
protected virtual IQueryable<IdentitySecurityLog> GetListQuery(
protected virtual async Task<IQueryable<IdentitySecurityLog>> GetListQueryAsync(
DateTime? startTime = null,
DateTime? endTime = null,
string applicationName = null,
@ -92,9 +100,10 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
Guid? userId = null,
string userName = null,
string clientId = null,
string correlationId = null)
string correlationId = null,
CancellationToken cancellationToken = default)
{
return DbSet.AsNoTracking()
return (await GetDbSetAsync()).AsNoTracking()
.WhereIf(startTime.HasValue, securityLog => securityLog.CreationTime >= startTime.Value)
.WhereIf(endTime.HasValue, securityLog => securityLog.CreationTime < endTime.Value.AddDays(1).Date)
.WhereIf(!applicationName.IsNullOrWhiteSpace(), securityLog => securityLog.ApplicationName == applicationName)

8
modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityClaimTypeRepository.cs

@ -22,7 +22,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
Guid? ignoredId = null,
CancellationToken cancellationToken = default)
{
return await DbSet
return await (await GetDbSetAsync())
.WhereIf(ignoredId != null, ct => ct.Id != ignoredId)
.CountAsync(ct => ct.Name == name, GetCancellationToken(cancellationToken)) > 0;
}
@ -34,7 +34,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
string filter,
CancellationToken cancellationToken = default)
{
var identityClaimTypes = await DbSet
var identityClaimTypes = await (await GetDbSetAsync())
.WhereIf(
!filter.IsNullOrWhiteSpace(),
u =>
@ -51,7 +51,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
string filter = null,
CancellationToken cancellationToken = default)
{
return await DbSet
return await (await GetDbSetAsync())
.WhereIf(
!filter.IsNullOrWhiteSpace(),
u =>
@ -59,4 +59,4 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
).LongCountAsync(GetCancellationToken(cancellationToken));
}
}
}
}

6
modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityLinkUserRepository.cs

@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
@ -20,7 +19,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
public async Task<IdentityLinkUser> FindAsync(IdentityLinkUserInfo sourceLinkUserInfo, IdentityLinkUserInfo targetLinkUserInfo, CancellationToken cancellationToken = default)
{
return await DbSet
return await (await GetDbSetAsync())
.OrderBy(x => x.Id).FirstOrDefaultAsync(x =>
x.SourceUserId == sourceLinkUserInfo.UserId && x.SourceTenantId == sourceLinkUserInfo.TenantId &&
x.TargetUserId == targetLinkUserInfo.UserId && x.TargetTenantId == targetLinkUserInfo.TenantId ||
@ -31,7 +30,8 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
public async Task<List<IdentityLinkUser>> GetListAsync(IdentityLinkUserInfo linkUserInfo, CancellationToken cancellationToken = default)
{
return await DbSet.Where(x =>
return await (await GetDbSetAsync())
.Where(x =>
x.SourceUserId == linkUserInfo.UserId && x.SourceTenantId == linkUserInfo.TenantId ||
x.TargetUserId == linkUserInfo.UserId && x.TargetTenantId == linkUserInfo.TenantId)
.ToListAsync(cancellationToken: GetCancellationToken(cancellationToken));

19
modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityRoleRepository.cs

@ -22,7 +22,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
bool includeDetails = true,
CancellationToken cancellationToken = default)
{
return await DbSet
return await (await GetDbSetAsync())
.IncludeDetails(includeDetails)
.OrderBy(x => x.Id)
.FirstOrDefaultAsync(r => r.NormalizedName == normalizedRoleName, GetCancellationToken(cancellationToken));
@ -36,7 +36,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
bool includeDetails = true,
CancellationToken cancellationToken = default)
{
return await DbSet
return await (await GetDbSetAsync())
.IncludeDetails(includeDetails)
.WhereIf(!filter.IsNullOrWhiteSpace(),
x => x.Name.Contains(filter) ||
@ -50,7 +50,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
IEnumerable<Guid> ids,
CancellationToken cancellationToken = default)
{
return await DbSet
return await (await GetDbSetAsync())
.Where(t => ids.Contains(t.Id))
.ToListAsync(GetCancellationToken(cancellationToken));
}
@ -58,23 +58,32 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
public virtual async Task<List<IdentityRole>> GetDefaultOnesAsync(
bool includeDetails = false, CancellationToken cancellationToken = default)
{
return await DbSet.IncludeDetails(includeDetails).Where(r => r.IsDefault).ToListAsync(GetCancellationToken(cancellationToken));
return await (await GetDbSetAsync())
.IncludeDetails(includeDetails)
.Where(r => r.IsDefault)
.ToListAsync(GetCancellationToken(cancellationToken));
}
public async Task<long> GetCountAsync(
string filter = null,
CancellationToken cancellationToken = default)
{
return await DbSet
return await (await GetDbSetAsync())
.WhereIf(!filter.IsNullOrWhiteSpace(),
x => x.Name.Contains(filter) ||
x.NormalizedName.Contains(filter))
.LongCountAsync(GetCancellationToken(cancellationToken));
}
[Obsolete("Use WithDetailsAsync")]
public override IQueryable<IdentityRole> WithDetails()
{
return GetQueryable().IncludeDetails();
}
public override async Task<IQueryable<IdentityRole>> WithDetailsAsync()
{
return (await GetQueryableAsync()).IncludeDetails();
}
}
}

93
modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreIdentityUserRepository.cs

@ -6,7 +6,6 @@ using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Internal;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
@ -24,7 +23,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
bool includeDetails = true,
CancellationToken cancellationToken = default)
{
return await DbSet
return await (await GetDbSetAsync())
.IncludeDetails(includeDetails)
.OrderBy(x => x.Id)
.FirstOrDefaultAsync(
@ -37,20 +36,21 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
Guid id,
CancellationToken cancellationToken = default)
{
var query = from userRole in DbContext.Set<IdentityUserRole>()
join role in DbContext.Roles on userRole.RoleId equals role.Id
var dbContext = await GetDbContextAsync();
var query = from userRole in dbContext.Set<IdentityUserRole>()
join role in dbContext.Roles on userRole.RoleId equals role.Id
where userRole.UserId == id
select role.Name;
var organizationUnitIds = DbContext.Set<IdentityUserOrganizationUnit>().Where(q => q.UserId == id).Select(q => q.OrganizationUnitId).ToArray();
var organizationUnitIds = dbContext.Set<IdentityUserOrganizationUnit>().Where(q => q.UserId == id).Select(q => q.OrganizationUnitId).ToArray();
var organizationRoleIds = await (
from ouRole in DbContext.Set<OrganizationUnitRole>()
join ou in DbContext.Set<OrganizationUnit>() on ouRole.OrganizationUnitId equals ou.Id
from ouRole in dbContext.Set<OrganizationUnitRole>()
join ou in dbContext.Set<OrganizationUnit>() on ouRole.OrganizationUnitId equals ou.Id
where organizationUnitIds.Contains(ouRole.OrganizationUnitId)
select ouRole.RoleId
).ToListAsync(GetCancellationToken(cancellationToken));
var orgUnitRoleNameQuery = DbContext.Roles.Where(r => organizationRoleIds.Contains(r.Id)).Select(n => n.Name);
var orgUnitRoleNameQuery = dbContext.Roles.Where(r => organizationRoleIds.Contains(r.Id)).Select(n => n.Name);
var resultQuery = query.Union(orgUnitRoleNameQuery);
return await resultQuery.ToListAsync(GetCancellationToken(cancellationToken));
}
@ -59,10 +59,11 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
Guid id,
CancellationToken cancellationToken = default)
{
var query = from userOu in DbContext.Set<IdentityUserOrganizationUnit>()
join roleOu in DbContext.Set<OrganizationUnitRole>() on userOu.OrganizationUnitId equals roleOu.OrganizationUnitId
join ou in DbContext.Set<OrganizationUnit>() on roleOu.OrganizationUnitId equals ou.Id
join userOuRoles in DbContext.Roles on roleOu.RoleId equals userOuRoles.Id
var dbContext = await GetDbContextAsync();
var query = from userOu in dbContext.Set<IdentityUserOrganizationUnit>()
join roleOu in dbContext.Set<OrganizationUnitRole>() on userOu.OrganizationUnitId equals roleOu.OrganizationUnitId
join ou in dbContext.Set<OrganizationUnit>() on roleOu.OrganizationUnitId equals ou.Id
join userOuRoles in dbContext.Roles on roleOu.RoleId equals userOuRoles.Id
where userOu.UserId == id
select userOuRoles.Name;
@ -77,7 +78,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
bool includeDetails = true,
CancellationToken cancellationToken = default)
{
return await DbSet
return await (await GetDbSetAsync())
.IncludeDetails(includeDetails)
.Where(u => u.Logins.Any(login => login.LoginProvider == loginProvider && login.ProviderKey == providerKey))
.OrderBy(x=>x.Id)
@ -89,7 +90,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
bool includeDetails = true,
CancellationToken cancellationToken = default)
{
return await DbSet
return await (await GetDbSetAsync())
.IncludeDetails(includeDetails)
.OrderBy(x => x.Id)
.FirstOrDefaultAsync(u => u.NormalizedEmail == normalizedEmail, GetCancellationToken(cancellationToken));
@ -100,7 +101,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return await DbSet
return await (await GetDbSetAsync())
.IncludeDetails(includeDetails)
.Where(u => u.Claims.Any(c => c.ClaimType == claim.Type && c.ClaimValue == claim.Value))
.ToListAsync(GetCancellationToken(cancellationToken));
@ -111,7 +112,9 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var role = await DbContext.Roles
var dbContext = await GetDbContextAsync();
var role = await dbContext.Roles
.Where(x => x.NormalizedName == normalizedRoleName)
.OrderBy(x => x.Id)
.FirstOrDefaultAsync(GetCancellationToken(cancellationToken));
@ -121,7 +124,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
return new List<IdentityUser>();
}
return await DbSet
return await dbContext.Users
.IncludeDetails(includeDetails)
.Where(u => u.Roles.Any(r => r.RoleId == role.Id))
.ToListAsync(GetCancellationToken(cancellationToken));
@ -135,7 +138,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return await DbSet
return await (await GetDbSetAsync())
.IncludeDetails(includeDetails)
.WhereIf(
!filter.IsNullOrWhiteSpace(),
@ -156,24 +159,26 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var query = from userRole in DbContext.Set<IdentityUserRole>()
join role in DbContext.Roles.IncludeDetails(includeDetails) on userRole.RoleId equals role.Id
var dbContext = await GetDbContextAsync();
var query = from userRole in dbContext.Set<IdentityUserRole>()
join role in dbContext.Roles.IncludeDetails(includeDetails) on userRole.RoleId equals role.Id
where userRole.UserId == id
select role;
//TODO: Needs improvement
var userOrganizationsQuery = from userOrg in DbContext.Set<IdentityUserOrganizationUnit>()
join ou in DbContext.OrganizationUnits.IncludeDetails(includeDetails) on userOrg.OrganizationUnitId equals ou.Id
var userOrganizationsQuery = from userOrg in dbContext.Set<IdentityUserOrganizationUnit>()
join ou in dbContext.OrganizationUnits.IncludeDetails(includeDetails) on userOrg.OrganizationUnitId equals ou.Id
where userOrg.UserId == id
select ou;
var orgUserRoleQuery = DbContext.Set<OrganizationUnitRole>()
var orgUserRoleQuery = dbContext.Set<OrganizationUnitRole>()
.Where(q => userOrganizationsQuery
.Select(t => t.Id)
.Contains(q.OrganizationUnitId))
.Select(t => t.RoleId);
var orgRoles = DbContext.Roles.Where(q => orgUserRoleQuery.Contains(q.Id));
var orgRoles = dbContext.Roles.Where(q => orgUserRoleQuery.Contains(q.Id));
var resultQuery = query.Union(orgRoles);
return await resultQuery.ToListAsync(GetCancellationToken(cancellationToken));
@ -183,7 +188,8 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
string filter = null,
CancellationToken cancellationToken = default)
{
return await this.WhereIf(
return await (await GetDbSetAsync())
.WhereIf(
!filter.IsNullOrWhiteSpace(),
u =>
u.UserName.Contains(filter) ||
@ -200,9 +206,11 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var query = from userOU in DbContext.Set<IdentityUserOrganizationUnit>()
join ou in DbContext.OrganizationUnits.IncludeDetails(includeDetails) on userOU.OrganizationUnitId equals ou.Id
where userOU.UserId == id
var dbContext = await GetDbContextAsync();
var query = from userOu in dbContext.Set<IdentityUserOrganizationUnit>()
join ou in dbContext.OrganizationUnits.IncludeDetails(includeDetails) on userOu.OrganizationUnitId equals ou.Id
where userOu.UserId == id
select ou;
return await query.ToListAsync(GetCancellationToken(cancellationToken));
@ -213,10 +221,13 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
CancellationToken cancellationToken = default
)
{
var query = from userOu in DbContext.Set<IdentityUserOrganizationUnit>()
join user in DbSet on userOu.UserId equals user.Id
var dbContext = await GetDbContextAsync();
var query = from userOu in dbContext.Set<IdentityUserOrganizationUnit>()
join user in dbContext.Users on userOu.UserId equals user.Id
where userOu.OrganizationUnitId == organizationUnitId
select user;
return await query.ToListAsync(GetCancellationToken(cancellationToken));
}
@ -225,10 +236,13 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
CancellationToken cancellationToken = default
)
{
var query = from userOu in DbContext.Set<IdentityUserOrganizationUnit>()
join user in DbSet on userOu.UserId equals user.Id
var dbContext = await GetDbContextAsync();
var query = from userOu in dbContext.Set<IdentityUserOrganizationUnit>()
join user in dbContext.Users on userOu.UserId equals user.Id
where organizationUnitIds.Contains(userOu.OrganizationUnitId)
select user;
return await query.ToListAsync(GetCancellationToken(cancellationToken));
}
@ -237,17 +251,26 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
CancellationToken cancellationToken = default
)
{
var query = from userOu in DbContext.Set<IdentityUserOrganizationUnit>()
join user in DbSet on userOu.UserId equals user.Id
join ou in DbContext.Set<OrganizationUnit>() on userOu.OrganizationUnitId equals ou.Id
var dbContext = await GetDbContextAsync();
var query = from userOu in dbContext.Set<IdentityUserOrganizationUnit>()
join user in dbContext.Users on userOu.UserId equals user.Id
join ou in dbContext.Set<OrganizationUnit>() on userOu.OrganizationUnitId equals ou.Id
where ou.Code.StartsWith(code)
select user;
return await query.ToListAsync(GetCancellationToken(cancellationToken));
}
[Obsolete("Use WithDetailsAsync method.")]
public override IQueryable<IdentityUser> WithDetails()
{
return GetQueryable().IncludeDetails();
}
public override async Task<IQueryable<IdentityUser>> WithDetailsAsync()
{
return (await GetQueryableAsync()).IncludeDetails();
}
}
}

66
modules/identity/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EntityFrameworkCore/EfCoreOrganizationUnitRepository.cs

@ -3,6 +3,7 @@ using System;
using System.Collections.Generic;
using System.Linq.Dynamic.Core;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
@ -25,7 +26,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return await DbSet
return await (await GetDbSetAsync())
.IncludeDetails(includeDetails)
.Where(x => x.ParentId == parentId)
.ToListAsync(GetCancellationToken(cancellationToken));
@ -37,7 +38,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return await DbSet
return await (await GetDbSetAsync())
.IncludeDetails(includeDetails)
.Where(ou => ou.Code.StartsWith(code) && ou.Id != parentId.Value)
.ToListAsync(GetCancellationToken(cancellationToken));
@ -50,7 +51,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
bool includeDetails = true,
CancellationToken cancellationToken = default)
{
return await DbSet
return await (await GetDbSetAsync())
.IncludeDetails(includeDetails)
.OrderBy(sorting ?? nameof(OrganizationUnit.DisplayName))
.PageBy(skipCount, maxResultCount)
@ -62,7 +63,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return await DbSet
return await (await GetDbSetAsync())
.IncludeDetails(includeDetails)
.Where(t => ids.Contains(t.Id))
.ToListAsync(GetCancellationToken(cancellationToken));
@ -73,7 +74,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
bool includeDetails = true,
CancellationToken cancellationToken = default)
{
return await DbSet
return await (await GetDbSetAsync())
.IncludeDetails(includeDetails)
.OrderBy(x => x.Id)
.FirstOrDefaultAsync(
@ -90,10 +91,13 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var query = from organizationRole in DbContext.Set<OrganizationUnitRole>()
join role in DbContext.Roles.IncludeDetails(includeDetails) on organizationRole.RoleId equals role.Id
var dbContext = await GetDbContextAsync();
var query = from organizationRole in dbContext.Set<OrganizationUnitRole>()
join role in dbContext.Roles.IncludeDetails(includeDetails) on organizationRole.RoleId equals role.Id
where organizationRole.OrganizationUnitId == organizationUnit.Id
select role;
query = query
.OrderBy(sorting ?? nameof(IdentityRole.Name))
.PageBy(skipCount, maxResultCount);
@ -105,8 +109,10 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
OrganizationUnit organizationUnit,
CancellationToken cancellationToken = default)
{
var query = from organizationRole in DbContext.Set<OrganizationUnitRole>()
join role in DbContext.Roles on organizationRole.RoleId equals role.Id
var dbContext = await GetDbContextAsync();
var query = from organizationRole in dbContext.Set<OrganizationUnitRole>()
join role in dbContext.Roles on organizationRole.RoleId equals role.Id
where organizationRole.OrganizationUnitId == organizationUnit.Id
select role;
@ -123,8 +129,9 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
CancellationToken cancellationToken = default)
{
var roleIds = organizationUnit.Roles.Select(r => r.RoleId).ToList();
var dbContext = await GetDbContextAsync();
return await DbContext.Roles
return await dbContext.Roles
.Where(r => !roleIds.Contains(r.Id))
.IncludeDetails(includeDetails)
.WhereIf(!filter.IsNullOrWhiteSpace(), r => r.Name.Contains(filter))
@ -139,8 +146,9 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
CancellationToken cancellationToken = default)
{
var roleIds = organizationUnit.Roles.Select(r => r.RoleId).ToList();
var dbContext = await GetDbContextAsync();
return await DbContext.Roles
return await dbContext.Roles
.Where(r => !roleIds.Contains(r.Id))
.WhereIf(!filter.IsNullOrWhiteSpace(), r => r.Name.Contains(filter))
.CountAsync(cancellationToken);
@ -155,7 +163,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var query = CreateGetMembersFilteredQuery(organizationUnit, filter);
var query = await CreateGetMembersFilteredQueryAsync(organizationUnit, filter);
return await query.IncludeDetails(includeDetails).OrderBy(sorting ?? nameof(IdentityUser.UserName))
.PageBy(skipCount, maxResultCount)
@ -167,7 +175,7 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
string filter = null,
CancellationToken cancellationToken = default)
{
var query = CreateGetMembersFilteredQuery(organizationUnit, filter);
var query = await CreateGetMembersFilteredQueryAsync(organizationUnit, filter);
return await query.CountAsync(GetCancellationToken(cancellationToken));
}
@ -181,11 +189,13 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var userIdsInOrganizationUnit = DbContext.Set<IdentityUserOrganizationUnit>()
var dbContext = await GetDbContextAsync();
var userIdsInOrganizationUnit = dbContext.Set<IdentityUserOrganizationUnit>()
.Where(uou => uou.OrganizationUnitId == organizationUnit.Id)
.Select(uou => uou.UserId);
var query = DbContext.Users
var query = dbContext.Users
.Where(u => !userIdsInOrganizationUnit.Contains(u.Id));
if (!filter.IsNullOrWhiteSpace())
@ -209,11 +219,13 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
string filter = null,
CancellationToken cancellationToken = default)
{
var userIdsInOrganizationUnit = DbContext.Set<IdentityUserOrganizationUnit>()
var dbContext = await GetDbContextAsync();
var userIdsInOrganizationUnit = dbContext.Set<IdentityUserOrganizationUnit>()
.Where(uou => uou.OrganizationUnitId == organizationUnit.Id)
.Select(uou => uou.UserId);
return await DbContext.Users
return await dbContext.Users
.Where(u => !userIdsInOrganizationUnit.Contains(u.Id))
.WhereIf(!filter.IsNullOrWhiteSpace(), u =>
u.UserName.Contains(filter) ||
@ -222,11 +234,17 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
.CountAsync(cancellationToken);
}
[Obsolete("Use WithDetailsAsync method.")]
public override IQueryable<OrganizationUnit> WithDetails()
{
return GetQueryable().IncludeDetails();
}
public override async Task<IQueryable<OrganizationUnit>> WithDetailsAsync()
{
return (await GetQueryableAsync()).IncludeDetails();
}
public virtual Task RemoveAllRolesAsync(
OrganizationUnit organizationUnit,
CancellationToken cancellationToken = default)
@ -239,17 +257,21 @@ namespace Volo.Abp.Identity.EntityFrameworkCore
OrganizationUnit organizationUnit,
CancellationToken cancellationToken = default)
{
var ouMembersQuery = await DbContext.Set<IdentityUserOrganizationUnit>()
var dbContext = await GetDbContextAsync();
var ouMembersQuery = await dbContext.Set<IdentityUserOrganizationUnit>()
.Where(q => q.OrganizationUnitId == organizationUnit.Id)
.ToListAsync(GetCancellationToken(cancellationToken));
DbContext.Set<IdentityUserOrganizationUnit>().RemoveRange(ouMembersQuery);
dbContext.Set<IdentityUserOrganizationUnit>().RemoveRange(ouMembersQuery);
}
protected virtual IQueryable<IdentityUser> CreateGetMembersFilteredQuery(OrganizationUnit organizationUnit, string filter = null)
protected virtual async Task<IQueryable<IdentityUser>> CreateGetMembersFilteredQueryAsync(OrganizationUnit organizationUnit, string filter = null)
{
var query = from userOu in DbContext.Set<IdentityUserOrganizationUnit>()
join user in DbContext.Users on userOu.UserId equals user.Id
var dbContext = await GetDbContextAsync();
var query = from userOu in dbContext.Set<IdentityUserOrganizationUnit>()
join user in dbContext.Users on userOu.UserId equals user.Id
where userOu.OrganizationUnitId == organizationUnit.Id
select user;

8
modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityClaimTypeRepository.cs

@ -24,13 +24,13 @@ namespace Volo.Abp.Identity.MongoDB
{
if (ignoredId == null)
{
return await GetMongoQueryable()
return await (await GetMongoQueryableAsync(cancellationToken))
.Where(ct => ct.Name == name)
.AnyAsync(GetCancellationToken(cancellationToken));
}
else
{
return await GetMongoQueryable()
return await (await GetMongoQueryableAsync(cancellationToken))
.Where(ct => ct.Id != ignoredId && ct.Name == name)
.AnyAsync(GetCancellationToken(cancellationToken));
}
@ -43,7 +43,7 @@ namespace Volo.Abp.Identity.MongoDB
string filter,
CancellationToken cancellationToken = default)
{
return await GetMongoQueryable()
return await (await GetMongoQueryableAsync(cancellationToken))
.WhereIf<IdentityClaimType, IMongoQueryable<IdentityClaimType>>(
!filter.IsNullOrWhiteSpace(),
u =>
@ -59,7 +59,7 @@ namespace Volo.Abp.Identity.MongoDB
string filter = null,
CancellationToken cancellationToken = default)
{
return await GetMongoQueryable()
return await (await GetMongoQueryableAsync(cancellationToken))
.WhereIf<IdentityClaimType, IMongoQueryable<IdentityClaimType>>(
!filter.IsNullOrWhiteSpace(),
u =>

4
modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityLinkUserRepository.cs

@ -19,7 +19,7 @@ namespace Volo.Abp.Identity.MongoDB
public async Task<IdentityLinkUser> FindAsync(IdentityLinkUserInfo sourceLinkUserInfo, IdentityLinkUserInfo targetLinkUserInfo, CancellationToken cancellationToken = default)
{
return await GetMongoQueryable()
return await (await GetMongoQueryableAsync(cancellationToken))
.OrderBy(x => x.Id).FirstOrDefaultAsync(x =>
x.SourceUserId == sourceLinkUserInfo.UserId && x.SourceTenantId == sourceLinkUserInfo.TenantId &&
x.TargetUserId == targetLinkUserInfo.UserId && x.TargetTenantId == targetLinkUserInfo.TenantId ||
@ -30,7 +30,7 @@ namespace Volo.Abp.Identity.MongoDB
public async Task<List<IdentityLinkUser>> GetListAsync(IdentityLinkUserInfo linkUserInfo, CancellationToken cancellationToken = default)
{
return await GetMongoQueryable().Where(x =>
return await (await GetMongoQueryableAsync(cancellationToken)).Where(x =>
x.SourceUserId == linkUserInfo.UserId && x.SourceTenantId == linkUserInfo.TenantId ||
x.TargetUserId == linkUserInfo.UserId && x.TargetTenantId == linkUserInfo.TenantId)
.ToListAsync(cancellationToken: GetCancellationToken(cancellationToken));

12
modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityRoleRepository.cs

@ -23,7 +23,7 @@ namespace Volo.Abp.Identity.MongoDB
bool includeDetails = true,
CancellationToken cancellationToken = default)
{
return await GetMongoQueryable()
return await (await GetMongoQueryableAsync(cancellationToken))
.OrderBy(x => x.Id)
.FirstOrDefaultAsync(r => r.NormalizedName == normalizedRoleName, GetCancellationToken(cancellationToken));
}
@ -36,7 +36,7 @@ namespace Volo.Abp.Identity.MongoDB
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return await GetMongoQueryable()
return await (await GetMongoQueryableAsync(cancellationToken))
.WhereIf(!filter.IsNullOrWhiteSpace(),
x => x.Name.Contains(filter) ||
x.NormalizedName.Contains(filter))
@ -50,7 +50,7 @@ namespace Volo.Abp.Identity.MongoDB
IEnumerable<Guid> ids,
CancellationToken cancellationToken = default)
{
return await GetMongoQueryable()
return await (await GetMongoQueryableAsync(cancellationToken))
.Where(t => ids.Contains(t.Id))
.ToListAsync(GetCancellationToken(cancellationToken));
}
@ -59,14 +59,16 @@ namespace Volo.Abp.Identity.MongoDB
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return await GetMongoQueryable().Where(r => r.IsDefault).ToListAsync(cancellationToken: GetCancellationToken(cancellationToken));
return await (await GetMongoQueryableAsync(cancellationToken))
.Where(r => r.IsDefault)
.ToListAsync(GetCancellationToken(cancellationToken));
}
public async Task<long> GetCountAsync(
string filter = null,
CancellationToken cancellationToken = default)
{
return await GetMongoQueryable()
return await (await GetMongoQueryableAsync(cancellationToken))
.WhereIf(!filter.IsNullOrWhiteSpace(),
x => x.Name.Contains(filter) ||
x.NormalizedName.Contains(filter))

10
modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentitySecurityLogRepository.cs

@ -35,7 +35,7 @@ namespace Volo.Abp.Identity.MongoDB
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var query = GetListQuery(
var query = await GetListQueryAsync(
startTime,
endTime,
applicationName,
@ -65,7 +65,7 @@ namespace Volo.Abp.Identity.MongoDB
string correlationId = null,
CancellationToken cancellationToken = default)
{
var query = GetListQuery(
var query = await GetListQueryAsync(
startTime,
endTime,
applicationName,
@ -85,11 +85,11 @@ namespace Volo.Abp.Identity.MongoDB
public async Task<IdentitySecurityLog> GetByUserIdAsync(Guid id, Guid userId, bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return await GetMongoQueryable().OrderBy(x => x.Id).FirstOrDefaultAsync(x => x.Id == id && x.UserId == userId,
return await (await GetMongoQueryableAsync(cancellationToken)).OrderBy(x => x.Id).FirstOrDefaultAsync(x => x.Id == id && x.UserId == userId,
GetCancellationToken(cancellationToken));
}
protected virtual IQueryable<IdentitySecurityLog> GetListQuery(
protected virtual async Task<IQueryable<IdentitySecurityLog>> GetListQueryAsync(
DateTime? startTime = null,
DateTime? endTime = null,
string applicationName = null,
@ -100,7 +100,7 @@ namespace Volo.Abp.Identity.MongoDB
string clientId = null,
string correlationId = null)
{
return GetMongoQueryable()
return (await GetMongoQueryableAsync())
.WhereIf(startTime.HasValue, securityLog => securityLog.CreationTime >= startTime.Value)
.WhereIf(endTime.HasValue, securityLog => securityLog.CreationTime < endTime.Value.AddDays(1).Date)
.WhereIf(!applicationName.IsNullOrWhiteSpace(),

65
modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoIdentityUserRepository.cs

@ -24,7 +24,7 @@ namespace Volo.Abp.Identity.MongoDB
bool includeDetails = true,
CancellationToken cancellationToken = default)
{
return await GetMongoQueryable()
return await (await GetMongoQueryableAsync(cancellationToken))
.OrderBy(x => x.Id)
.FirstOrDefaultAsync(
u => u.NormalizedUserName == normalizedUserName,
@ -40,14 +40,17 @@ namespace Volo.Abp.Identity.MongoDB
var organizationUnitIds = user.OrganizationUnits
.Select(r => r.OrganizationUnitId)
.ToArray();
var organizationUnits = DbContext.OrganizationUnits
var dbContext = await GetDbContextAsync(cancellationToken);
var organizationUnits = dbContext.OrganizationUnits
.AsQueryable()
.Where(ou => organizationUnitIds.Contains(ou.Id))
.ToArray();
var orgUnitRoleIds = organizationUnits.SelectMany(x => x.Roles.Select(r => r.RoleId)).ToArray();
var roleIds = user.Roles.Select(r => r.RoleId).ToArray();
var allRoleIds = orgUnitRoleIds.Union(roleIds);
return await DbContext.Roles.AsQueryable().Where(r => allRoleIds.Contains(r.Id)).Select(r => r.Name).ToListAsync(GetCancellationToken(cancellationToken));
return await dbContext.Roles.AsQueryable().Where(r => allRoleIds.Contains(r.Id)).Select(r => r.Name).ToListAsync(GetCancellationToken(cancellationToken));
}
public async Task<List<string>> GetRoleNamesInOrganizationUnitAsync(
@ -60,14 +63,16 @@ namespace Volo.Abp.Identity.MongoDB
.Select(r => r.OrganizationUnitId)
.ToArray();
var organizationUnits = DbContext.OrganizationUnits
var dbContext = await GetDbContextAsync(cancellationToken);
var organizationUnits = dbContext.OrganizationUnits
.AsQueryable()
.Where(ou => organizationUnitIds.Contains(ou.Id))
.ToArray();
var roleIds = organizationUnits.SelectMany(x => x.Roles.Select(r => r.RoleId)).ToArray();
return await DbContext.Roles //TODO: Such usage suppress filters!
return await dbContext.Roles //TODO: Such usage suppress filters!
.AsQueryable()
.Where(r => roleIds.Contains(r.Id))
.Select(r => r.Name)
@ -80,7 +85,7 @@ namespace Volo.Abp.Identity.MongoDB
bool includeDetails = true,
CancellationToken cancellationToken = default)
{
return await GetMongoQueryable()
return await (await GetMongoQueryableAsync(cancellationToken))
.Where(u => u.Logins.Any(login => login.LoginProvider == loginProvider && login.ProviderKey == providerKey))
.OrderBy(x => x.Id)
.FirstOrDefaultAsync(GetCancellationToken(cancellationToken));
@ -91,7 +96,7 @@ namespace Volo.Abp.Identity.MongoDB
bool includeDetails = true,
CancellationToken cancellationToken = default)
{
return await GetMongoQueryable()
return await (await GetMongoQueryableAsync(cancellationToken))
.OrderBy(x => x.Id).FirstOrDefaultAsync(u => u.NormalizedEmail == normalizedEmail, GetCancellationToken(cancellationToken));
}
@ -100,7 +105,7 @@ namespace Volo.Abp.Identity.MongoDB
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return await GetMongoQueryable()
return await (await GetMongoQueryableAsync(cancellationToken))
.Where(u => u.Claims.Any(c => c.ClaimType == claim.Type && c.ClaimValue == claim.Value))
.ToListAsync(GetCancellationToken(cancellationToken));
}
@ -110,19 +115,21 @@ namespace Volo.Abp.Identity.MongoDB
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var role = await DbContext.Roles.AsQueryable()
cancellationToken = GetCancellationToken(cancellationToken);
var role = await (await GetDbContextAsync(cancellationToken)).Roles.AsQueryable() //TODO: Such usages breaks data filters
.Where(x => x.NormalizedName == normalizedRoleName)
.OrderBy(x => x.Id)
.FirstOrDefaultAsync(GetCancellationToken(cancellationToken));
.FirstOrDefaultAsync(cancellationToken);
if (role == null)
{
return new List<IdentityUser>();
}
return await GetMongoQueryable()
return await (await GetMongoQueryableAsync(cancellationToken))
.Where(u => u.Roles.Any(r => r.RoleId == role.Id))
.ToListAsync(GetCancellationToken(cancellationToken));
.ToListAsync(cancellationToken);
}
public virtual async Task<List<IdentityUser>> GetListAsync(
@ -133,7 +140,7 @@ namespace Volo.Abp.Identity.MongoDB
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return await GetMongoQueryable()
return await (await GetMongoQueryableAsync(cancellationToken))
.WhereIf<IdentityUser, IMongoQueryable<IdentityUser>>(
!filter.IsNullOrWhiteSpace(),
u =>
@ -158,14 +165,17 @@ namespace Volo.Abp.Identity.MongoDB
var organizationUnitIds = user.OrganizationUnits
.Select(r => r.OrganizationUnitId)
.ToArray();
var organizationUnits = DbContext.OrganizationUnits
var dbContext = await GetDbContextAsync(cancellationToken);
var organizationUnits = dbContext.OrganizationUnits
.AsQueryable()
.Where(ou => organizationUnitIds.Contains(ou.Id))
.ToArray();
var orgUnitRoleIds = organizationUnits.SelectMany(x => x.Roles.Select(r => r.RoleId)).ToArray();
var roleIds = user.Roles.Select(r => r.RoleId).ToArray();
var allRoleIds = orgUnitRoleIds.Union(roleIds);
return await DbContext.Roles.AsQueryable().Where(r => allRoleIds.Contains(r.Id)).ToListAsync(GetCancellationToken(cancellationToken));
return await dbContext.Roles.AsQueryable().Where(r => allRoleIds.Contains(r.Id)).ToListAsync(GetCancellationToken(cancellationToken));
}
public async Task<List<OrganizationUnit>> GetOrganizationUnitsAsync(
@ -175,17 +185,19 @@ namespace Volo.Abp.Identity.MongoDB
{
var user = await GetAsync(id, cancellationToken: GetCancellationToken(cancellationToken));
var organizationUnitIds = user.OrganizationUnits.Select(r => r.OrganizationUnitId);
return await DbContext.OrganizationUnits.AsQueryable()
var dbContext = await GetDbContextAsync(cancellationToken);
return await dbContext.OrganizationUnits.AsQueryable()
.Where(ou => organizationUnitIds.Contains(ou.Id))
.ToListAsync(GetCancellationToken(cancellationToken))
;
.ToListAsync(GetCancellationToken(cancellationToken));
}
public virtual async Task<long> GetCountAsync(
string filter = null,
CancellationToken cancellationToken = default)
{
return await GetMongoQueryable()
return await (await GetMongoQueryableAsync(cancellationToken))
.WhereIf<IdentityUser, IMongoQueryable<IdentityUser>>(
!filter.IsNullOrWhiteSpace(),
u =>
@ -202,7 +214,7 @@ namespace Volo.Abp.Identity.MongoDB
Guid organizationUnitId,
CancellationToken cancellationToken = default)
{
var result = await GetMongoQueryable()
var result = await (await GetMongoQueryableAsync(cancellationToken))
.Where(u => u.OrganizationUnits.Any(uou => uou.OrganizationUnitId == organizationUnitId))
.ToListAsync(GetCancellationToken(cancellationToken))
;
@ -213,7 +225,7 @@ namespace Volo.Abp.Identity.MongoDB
List<Guid> organizationUnitIds,
CancellationToken cancellationToken = default)
{
var result = await GetMongoQueryable()
var result = await (await GetMongoQueryableAsync(cancellationToken))
.Where(u => u.OrganizationUnits.Any(uou => organizationUnitIds.Contains(uou.OrganizationUnitId)))
.ToListAsync(GetCancellationToken(cancellationToken))
;
@ -224,16 +236,17 @@ namespace Volo.Abp.Identity.MongoDB
string code,
CancellationToken cancellationToken = default)
{
var organizationUnitIds = await DbContext.OrganizationUnits.AsQueryable()
cancellationToken = GetCancellationToken(cancellationToken);
var organizationUnitIds = await (await GetDbContextAsync(cancellationToken)).OrganizationUnits.AsQueryable()
.Where(ou => ou.Code.StartsWith(code))
.Select(ou => ou.Id)
.ToListAsync(GetCancellationToken(cancellationToken))
.ToListAsync(cancellationToken)
;
return await GetMongoQueryable()
return await (await GetMongoQueryableAsync(cancellationToken))
.Where(u => u.OrganizationUnits.Any(uou => organizationUnitIds.Contains(uou.OrganizationUnitId)))
.ToListAsync(GetCancellationToken(cancellationToken))
;
.ToListAsync(cancellationToken);
}
}
}

62
modules/identity/src/Volo.Abp.Identity.MongoDB/Volo/Abp/Identity/MongoDB/MongoOrganizationUnitRepository.cs

@ -1,9 +1,7 @@
using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading;
@ -11,7 +9,6 @@ using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories.MongoDB;
using Volo.Abp.MongoDB;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Uow;
namespace Volo.Abp.Identity.MongoDB
{
@ -30,7 +27,7 @@ namespace Volo.Abp.Identity.MongoDB
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return await GetMongoQueryable()
return await (await GetMongoQueryableAsync(cancellationToken))
.Where(ou => ou.ParentId == parentId)
.ToListAsync(GetCancellationToken(cancellationToken));
}
@ -41,7 +38,7 @@ namespace Volo.Abp.Identity.MongoDB
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return await GetMongoQueryable()
return await (await GetMongoQueryableAsync(cancellationToken))
.Where(ou => ou.Code.StartsWith(code) && ou.Id != parentId.Value)
.ToListAsync(GetCancellationToken(cancellationToken));
}
@ -51,7 +48,7 @@ namespace Volo.Abp.Identity.MongoDB
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return await GetMongoQueryable()
return await (await GetMongoQueryableAsync(cancellationToken))
.Where(t => ids.Contains(t.Id))
.ToListAsync(GetCancellationToken(cancellationToken));
}
@ -63,7 +60,7 @@ namespace Volo.Abp.Identity.MongoDB
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return await GetMongoQueryable()
return await (await GetMongoQueryableAsync(cancellationToken))
.OrderBy(sorting ?? nameof(OrganizationUnit.DisplayName))
.As<IMongoQueryable<OrganizationUnit>>()
.PageBy<OrganizationUnit, IMongoQueryable<OrganizationUnit>>(skipCount, maxResultCount)
@ -75,7 +72,7 @@ namespace Volo.Abp.Identity.MongoDB
bool includeDetails = true,
CancellationToken cancellationToken = default)
{
return await GetMongoQueryable()
return await (await GetMongoQueryableAsync(cancellationToken))
.OrderBy(x => x.Id)
.FirstOrDefaultAsync(
ou => ou.DisplayName == displayName,
@ -92,7 +89,10 @@ namespace Volo.Abp.Identity.MongoDB
CancellationToken cancellationToken = default)
{
var roleIds = organizationUnit.Roles.Select(r => r.RoleId).ToArray();
return await ApplyDataFilters<IMongoQueryable<IdentityRole>, IdentityRole>(DbContext.Roles.AsQueryable().Where(r => roleIds.Contains(r.Id)))
var dbContext = await GetDbContextAsync(cancellationToken);
return await ApplyDataFilters<IMongoQueryable<IdentityRole>, IdentityRole>(
dbContext.Roles.AsQueryable().Where(r => roleIds.Contains(r.Id))
)
.OrderBy(sorting ?? nameof(IdentityRole.Name))
.As<IMongoQueryable<IdentityRole>>()
.PageBy<IdentityRole, IMongoQueryable<IdentityRole>>(skipCount, maxResultCount)
@ -104,7 +104,10 @@ namespace Volo.Abp.Identity.MongoDB
CancellationToken cancellationToken = default)
{
var roleIds = organizationUnit.Roles.Select(r => r.RoleId).ToArray();
return await ApplyDataFilters<IMongoQueryable<IdentityRole>, IdentityRole>( DbContext.Roles.AsQueryable().Where(r => roleIds.Contains(r.Id)))
var dbContext = await GetDbContextAsync(cancellationToken);
return await ApplyDataFilters<IMongoQueryable<IdentityRole>, IdentityRole>(
dbContext.Roles.AsQueryable().Where(r => roleIds.Contains(r.Id))
)
.As<IMongoQueryable<IdentityRole>>()
.CountAsync(cancellationToken);
}
@ -119,7 +122,8 @@ namespace Volo.Abp.Identity.MongoDB
CancellationToken cancellationToken = default)
{
var roleIds = organizationUnit.Roles.Select(r => r.RoleId).ToArray();
return await ApplyDataFilters<IMongoQueryable<IdentityRole>, IdentityRole>(DbContext.Roles.AsQueryable())
var dbContext = await GetDbContextAsync(cancellationToken);
return await ApplyDataFilters<IMongoQueryable<IdentityRole>, IdentityRole>(dbContext.Roles.AsQueryable())
.Where(r => !roleIds.Contains(r.Id))
.WhereIf(!filter.IsNullOrWhiteSpace(), r => r.Name.Contains(filter))
.OrderBy(sorting ?? nameof(IdentityRole.Name))
@ -134,7 +138,8 @@ namespace Volo.Abp.Identity.MongoDB
CancellationToken cancellationToken = default)
{
var roleIds = organizationUnit.Roles.Select(r => r.RoleId).ToArray();
return await ApplyDataFilters<IMongoQueryable<IdentityRole>, IdentityRole>(DbContext.Roles.AsQueryable())
var dbContext = await GetDbContextAsync(cancellationToken);
return await ApplyDataFilters<IMongoQueryable<IdentityRole>, IdentityRole>(dbContext.Roles.AsQueryable())
.Where(r => !roleIds.Contains(r.Id))
.WhereIf(!filter.IsNullOrWhiteSpace(), r => r.Name.Contains(filter))
.As<IMongoQueryable<IdentityRole>>()
@ -150,13 +155,13 @@ namespace Volo.Abp.Identity.MongoDB
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var query = CreateGetMembersFilteredQuery(organizationUnit, filter);
cancellationToken = GetCancellationToken(cancellationToken);
var query = await CreateGetMembersFilteredQueryAsync(organizationUnit, filter, cancellationToken);
return await query
.OrderBy(sorting ?? nameof(IdentityUser.UserName))
.As<IMongoQueryable<IdentityUser>>()
.PageBy<IdentityUser, IMongoQueryable<IdentityUser>>(skipCount, maxResultCount)
.ToListAsync(GetCancellationToken(cancellationToken));
.ToListAsync(cancellationToken);
}
public virtual async Task<int> GetMembersCountAsync(
@ -164,9 +169,9 @@ namespace Volo.Abp.Identity.MongoDB
string filter = null,
CancellationToken cancellationToken = default)
{
var query = CreateGetMembersFilteredQuery(organizationUnit, filter);
return await query.CountAsync(GetCancellationToken(cancellationToken));
cancellationToken = GetCancellationToken(cancellationToken);
var query = await CreateGetMembersFilteredQueryAsync(organizationUnit, filter, cancellationToken);
return await query.CountAsync(cancellationToken);
}
public async Task<List<IdentityUser>> GetUnaddedUsersAsync(
@ -178,7 +183,8 @@ namespace Volo.Abp.Identity.MongoDB
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return await ApplyDataFilters<IMongoQueryable<IdentityUser>, IdentityUser>(DbContext.Users.AsQueryable())
var dbContext = await GetDbContextAsync(cancellationToken);
return await ApplyDataFilters<IMongoQueryable<IdentityUser>, IdentityUser>(dbContext.Users.AsQueryable())
.Where(u => !u.OrganizationUnits.Any(uou => uou.OrganizationUnitId == organizationUnit.Id))
.WhereIf<IdentityUser, IMongoQueryable<IdentityUser>>(
!filter.IsNullOrWhiteSpace(),
@ -196,7 +202,8 @@ namespace Volo.Abp.Identity.MongoDB
public async Task<int> GetUnaddedUsersCountAsync(OrganizationUnit organizationUnit, string filter = null,
CancellationToken cancellationToken = default)
{
return await ApplyDataFilters<IMongoQueryable<IdentityUser>, IdentityUser>(DbContext.Users.AsQueryable())
var dbContext = await GetDbContextAsync(cancellationToken);
return await ApplyDataFilters<IMongoQueryable<IdentityUser>, IdentityUser>(dbContext.Users.AsQueryable())
.Where(u => !u.OrganizationUnits.Any(uou => uou.OrganizationUnitId == organizationUnit.Id))
.WhereIf<IdentityUser, IMongoQueryable<IdentityUser>>(
!filter.IsNullOrWhiteSpace(),
@ -217,7 +224,8 @@ namespace Volo.Abp.Identity.MongoDB
public virtual async Task RemoveAllMembersAsync(OrganizationUnit organizationUnit, CancellationToken cancellationToken = default)
{
var users = await ApplyDataFilters<IMongoQueryable<IdentityUser>, IdentityUser>(DbContext.Users.AsQueryable())
var dbContext = await GetDbContextAsync(cancellationToken);
var users = await ApplyDataFilters<IMongoQueryable<IdentityUser>, IdentityUser>(dbContext.Users.AsQueryable())
.Where(u => u.OrganizationUnits.Any(uou => uou.OrganizationUnitId == organizationUnit.Id))
.As<IMongoQueryable<IdentityUser>>()
.ToListAsync(GetCancellationToken(cancellationToken));
@ -225,13 +233,17 @@ namespace Volo.Abp.Identity.MongoDB
foreach (var user in users)
{
user.RemoveOrganizationUnit(organizationUnit.Id);
DbContext.Users.ReplaceOne(u => u.Id == user.Id, user);
await dbContext.Users.ReplaceOneAsync(u => u.Id == user.Id, user, cancellationToken: cancellationToken);
}
}
protected virtual IMongoQueryable<IdentityUser> CreateGetMembersFilteredQuery(OrganizationUnit organizationUnit, string filter = null)
protected virtual async Task<IMongoQueryable<IdentityUser>> CreateGetMembersFilteredQueryAsync(
OrganizationUnit organizationUnit,
string filter = null,
CancellationToken cancellationToken = default)
{
return ApplyDataFilters<IMongoQueryable<IdentityUser>, IdentityUser>(DbContext.Users.AsQueryable())
var dbContext = await GetDbContextAsync(cancellationToken);
return ApplyDataFilters<IMongoQueryable<IdentityUser>, IdentityUser>(dbContext.Users.AsQueryable())
.Where(u => u.OrganizationUnits.Any(uou => uou.OrganizationUnitId == organizationUnit.Id))
.WhereIf<IdentityUser, IMongoQueryable<IdentityUser>>(
!filter.IsNullOrWhiteSpace(),

34
modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/ApiResources/ApiResourceRepository.cs

@ -20,7 +20,7 @@ namespace Volo.Abp.IdentityServer.ApiResources
public async Task<ApiResource> FindByNameAsync(string apiResourceName, bool includeDetails = true, CancellationToken cancellationToken = default)
{
var query = from apiResource in DbSet.IncludeDetails(includeDetails)
var query = from apiResource in (await GetDbSetAsync()).IncludeDetails(includeDetails)
where apiResource.Name == apiResourceName
orderby apiResource.Id
select apiResource;
@ -31,7 +31,7 @@ namespace Volo.Abp.IdentityServer.ApiResources
public async Task<List<ApiResource>> FindByNameAsync(string[] apiResourceNames, bool includeDetails = true,
CancellationToken cancellationToken = default)
{
var query = from apiResource in DbSet.IncludeDetails(includeDetails)
var query = from apiResource in (await GetDbSetAsync()).IncludeDetails(includeDetails)
where apiResourceNames.Contains(apiResource.Name)
orderby apiResource.Name
select apiResource;
@ -44,7 +44,7 @@ namespace Volo.Abp.IdentityServer.ApiResources
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var query = from api in DbSet.IncludeDetails(includeDetails)
var query = from api in (await GetDbSetAsync()).IncludeDetails(includeDetails)
where api.Scopes.Any(x => scopeNames.Contains(x.Scope))
select api;
@ -58,7 +58,7 @@ namespace Volo.Abp.IdentityServer.ApiResources
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return await DbSet
return await (await GetDbSetAsync())
.IncludeDetails(includeDetails)
.WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Name.Contains(filter) ||
x.Description.Contains(filter) ||
@ -70,41 +70,49 @@ namespace Volo.Abp.IdentityServer.ApiResources
public virtual async Task<bool> CheckNameExistAsync(string name, Guid? expectedId = null, CancellationToken cancellationToken = default)
{
return await DbSet.AnyAsync(ar => ar.Id != expectedId && ar.Name == name, GetCancellationToken(cancellationToken));
return await (await GetDbSetAsync()).AnyAsync(ar => ar.Id != expectedId && ar.Name == name, GetCancellationToken(cancellationToken));
}
public async override Task DeleteAsync(Guid id, bool autoSave = false, CancellationToken cancellationToken = default)
{
var resourceClaims = DbContext.Set<ApiResourceClaim>().Where(sc => sc.ApiResourceId == id);
var dbContext = await GetDbContextAsync();
var resourceClaims = dbContext.Set<ApiResourceClaim>().Where(sc => sc.ApiResourceId == id);
foreach (var scopeClaim in resourceClaims)
{
DbContext.Set<ApiResourceClaim>().Remove(scopeClaim);
dbContext.Set<ApiResourceClaim>().Remove(scopeClaim);
}
var resourceScopes = DbContext.Set<ApiResourceScope>().Where(s => s.ApiResourceId == id);
var resourceScopes = dbContext.Set<ApiResourceScope>().Where(s => s.ApiResourceId == id);
foreach (var scope in resourceScopes)
{
DbContext.Set<ApiResourceScope>().Remove(scope);
dbContext.Set<ApiResourceScope>().Remove(scope);
}
var resourceSecrets = DbContext.Set<ApiResourceSecret>().Where(s => s.ApiResourceId == id);
var resourceSecrets = dbContext.Set<ApiResourceSecret>().Where(s => s.ApiResourceId == id);
foreach (var secret in resourceSecrets)
{
DbContext.Set<ApiResourceSecret>().Remove(secret);
dbContext.Set<ApiResourceSecret>().Remove(secret);
}
var apiResourceProperties = DbContext.Set<ApiResourceProperty>().Where(s => s.ApiResourceId == id);
var apiResourceProperties = dbContext.Set<ApiResourceProperty>().Where(s => s.ApiResourceId == id);
foreach (var property in apiResourceProperties)
{
DbContext.Set<ApiResourceProperty>().Remove(property);
dbContext.Set<ApiResourceProperty>().Remove(property);
}
await base.DeleteAsync(id, autoSave, cancellationToken);
}
[Obsolete("Use WithDetailsAsync method.")]
public override IQueryable<ApiResource> WithDetails()
{
return GetQueryable().IncludeDetails();
}
public override async Task<IQueryable<ApiResource>> WithDetailsAsync()
{
return (await GetQueryableAsync()).IncludeDetails();
}
}
}

25
modules/identityserver/src/Volo.Abp.IdentityServer.EntityFrameworkCore/Volo/Abp/IdentityServer/ApiScopes/ApiScopeRepository.cs

@ -20,7 +20,7 @@ namespace Volo.Abp.IdentityServer.ApiScopes
public async Task<ApiScope> GetByNameAsync(string scopeName, bool includeDetails = true, CancellationToken cancellationToken = default)
{
return await DbSet
return await (await GetDbSetAsync())
.OrderBy(x=>x.Id)
.FirstOrDefaultAsync(x => x.Name == scopeName, GetCancellationToken(cancellationToken));
}
@ -28,7 +28,7 @@ namespace Volo.Abp.IdentityServer.ApiScopes
public async Task<List<ApiScope>> GetListByNameAsync(string[] scopeNames, bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var query = from scope in DbSet.IncludeDetails(includeDetails)
var query = from scope in (await GetDbSetAsync()).IncludeDetails(includeDetails)
where scopeNames.Contains(scope.Name)
orderby scope.Id
select scope;
@ -38,7 +38,7 @@ namespace Volo.Abp.IdentityServer.ApiScopes
public async Task<List<ApiScope>> GetListAsync(string sorting, int skipCount, int maxResultCount, string filter = null, bool includeDetails = false, CancellationToken cancellationToken = default)
{
return await DbSet
return await (await GetDbSetAsync())
.IncludeDetails(includeDetails)
.WhereIf(!filter.IsNullOrWhiteSpace(), x => x.Name.Contains(filter) ||
x.Description.Contains(filter) ||
@ -50,29 +50,36 @@ namespace Volo.Abp.IdentityServer.ApiScopes
public async Task<bool> CheckNameExistAsync(string name, Guid? expectedId = null, CancellationToken cancellationToken = default)
{
return await DbSet.AnyAsync(x => x.Id != expectedId && x.Name == name, GetCancellationToken(cancellationToken));
return await (await GetDbSetAsync()).AnyAsync(x => x.Id != expectedId && x.Name == name, GetCancellationToken(cancellationToken));
}
public async override Task DeleteAsync(Guid id, bool autoSave = false, CancellationToken cancellationToken = new CancellationToken())
public override async Task DeleteAsync(Guid id, bool autoSave = false, CancellationToken cancellationToken = new CancellationToken())
{
var scopeClaims = DbContext.Set<ApiScopeClaim>().Where(sc => sc.ApiScopeId == id);
var dbContext = await GetDbContextAsync();
var scopeClaims = dbContext.Set<ApiScopeClaim>().Where(sc => sc.ApiScopeId == id);
foreach (var claim in scopeClaims)
{
DbContext.Set<ApiScopeClaim>().Remove(claim);
dbContext.Set<ApiScopeClaim>().Remove(claim);
}
var scopeProperties = DbContext.Set<ApiScopeProperty>().Where(s => s.ApiScopeId == id);
var scopeProperties = dbContext.Set<ApiScopeProperty>().Where(s => s.ApiScopeId == id);
foreach (var property in scopeProperties)
{
DbContext.Set<ApiScopeProperty>().Remove(property);
dbContext.Set<ApiScopeProperty>().Remove(property);
}
await base.DeleteAsync(id, autoSave, cancellationToken);
}
[Obsolete("Use WithDetailsAsync method.")]
public override IQueryable<ApiScope> WithDetails()
{
return GetQueryable().IncludeDetails();
}
public override async Task<IQueryable<ApiScope>> WithDetailsAsync()
{
return (await GetQueryableAsync()).IncludeDetails();
}
}
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save