diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Pagination/PagerModel.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Pagination/PagerModel.cs
index 980aacee8a..3c4eb1b88e 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Pagination/PagerModel.cs
+++ b/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
}
///
- /// Gets first two, previous & current & next, last two pages
+ /// Gets first two, previous, current, next, last two pages
///
private List GetPagesWithGaps()
{
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowActionFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowActionFilter.cs
index 552ce7e04e..43dedf916f 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowActionFilter.cs
+++ b/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))
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowPageFilter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowPageFilter.cs
index bcef10ecd4..960c47b591 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Uow/AbpUowPageFilter.cs
+++ b/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))
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpUnitOfWorkMiddleware.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpUnitOfWorkMiddleware.cs
index c9ac1be509..aeb6f8a8c0 100644
--- a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AbpUnitOfWorkMiddleware.cs
+++ b/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);
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AspNetCoreUnitOfWorkTransactionBehaviourProvider.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AspNetCoreUnitOfWorkTransactionBehaviourProvider.cs
new file mode 100644
index 0000000000..fd1d20d905
--- /dev/null
+++ b/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 options)
+ {
+ _httpContextAccessor = httpContextAccessor;
+ _options = options.Value;
+ }
+ }
+}
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AspNetCoreUnitOfWorkTransactionBehaviourProviderOptions.cs b/framework/src/Volo.Abp.AspNetCore/Volo/Abp/AspNetCore/Uow/AspNetCoreUnitOfWorkTransactionBehaviourProviderOptions.cs
new file mode 100644
index 0000000000..dd612a008d
--- /dev/null
+++ b/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 NonTransactionalUrls { get; }
+
+ public AspNetCoreUnitOfWorkTransactionBehaviourProviderOptions()
+ {
+ NonTransactionalUrls = new List
+ {
+ "/connect/"
+ };
+ }
+ }
+}
diff --git a/framework/src/Volo.Abp.Authorization/Microsoft/AspNetCore/Authorization/AuthorizationOptionsExtensions.cs b/framework/src/Volo.Abp.Authorization/Microsoft/AspNetCore/Authorization/AuthorizationOptionsExtensions.cs
index 499c2431c5..516e842563 100644
--- a/framework/src/Volo.Abp.Authorization/Microsoft/AspNetCore/Authorization/AuthorizationOptionsExtensions.cs
+++ b/framework/src/Volo.Abp.Authorization/Microsoft/AspNetCore/Authorization/AuthorizationOptionsExtensions.cs
@@ -11,9 +11,9 @@ namespace Microsoft.AspNetCore.Authorization
///
/// Gets all policies.
- ///
+ ///
/// IMPORTANT NOTE: Use this method carefully.
- /// It relies on reflection to get all policies from a private field of the .
+ /// It relies on reflection to get all policies from a private field of the .
/// This method may be removed in the future if internals of changes.
///
///
@@ -23,4 +23,4 @@ namespace Microsoft.AspNetCore.Authorization
return ((IDictionary) PolicyMapProperty.GetValue(options)).Keys.ToList();
}
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs
index 602fdd9c50..38873fe1b8 100644
--- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs
+++ b/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.
///
public bool IsEnabled { get; set; }
@@ -64,8 +64,8 @@ namespace Volo.Abp.Authorization.Permissions
///
/// Name of the property
///
- /// Returns the value in the dictionary by given .
- /// Returns null if given is not present in the dictionary.
+ /// Returns the value in the dictionary by given .
+ /// Returns null if given is not present in the dictionary.
///
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}]";
}
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionGroupDefinition.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionGroupDefinition.cs
index 5038e8e064..6d3a937a94 100644
--- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionGroupDefinition.cs
+++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/PermissionGroupDefinition.cs
@@ -36,8 +36,8 @@ namespace Volo.Abp.Authorization.Permissions
///
/// Name of the property
///
- /// Returns the value in the dictionary by given .
- /// Returns null if given is not present in the dictionary.
+ /// Returns the value in the dictionary by given .
+ /// Returns null if given is not present in the dictionary.
///
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;
}
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IAsyncBackgroundJob.cs b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IAsyncBackgroundJob.cs
index 262d95d35b..18f38128db 100644
--- a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IAsyncBackgroundJob.cs
+++ b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IAsyncBackgroundJob.cs
@@ -8,9 +8,9 @@ namespace Volo.Abp.BackgroundJobs
public interface IAsyncBackgroundJob
{
///
- /// Executes the job with the .
+ /// Executes the job with the .
///
/// Job arguments.
Task ExecuteAsync(TArgs args);
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IBackgroundJob.cs b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IBackgroundJob.cs
index e7c942ec4c..94b75f4c91 100644
--- a/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IBackgroundJob.cs
+++ b/framework/src/Volo.Abp.BackgroundJobs.Abstractions/Volo/Abp/BackgroundJobs/IBackgroundJob.cs
@@ -6,9 +6,9 @@
public interface IBackgroundJob
{
///
- /// Executes the job with the .
+ /// Executes the job with the .
///
/// Job arguments.
void Execute(TArgs args);
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.BlazoriseUI/AbpCrudPageBase.cs b/framework/src/Volo.Abp.BlazoriseUI/AbpCrudPageBase.cs
index 612034af19..9a820600bd 100644
--- a/framework/src/Volo.Abp.BlazoriseUI/AbpCrudPageBase.cs
+++ b/framework/src/Volo.Abp.BlazoriseUI/AbpCrudPageBase.cs
@@ -439,10 +439,10 @@ namespace Volo.Abp.BlazoriseUI
}
///
- /// Calls IAuthorizationService.CheckAsync for the given .
+ /// Calls IAuthorizationService.CheckAsync for the given .
/// Throws if given policy was not granted for the current user.
///
- /// Does nothing if is null or empty.
+ /// Does nothing if is null or empty.
///
/// A policy name to check
protected virtual async Task CheckPolicyAsync([CanBeNull] string policyName)
diff --git a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainerFactoryExtensions.cs b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainerFactoryExtensions.cs
index 1dc51a2a72..e2d5ff25e9 100644
--- a/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainerFactoryExtensions.cs
+++ b/framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/BlobContainerFactoryExtensions.cs
@@ -6,7 +6,6 @@
/// Gets a named container.
///
/// The blob container manager
- /// Cancellation token
///
/// The container object.
///
@@ -19,4 +18,4 @@
);
}
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.Core/System/AbpStringExtensions.cs b/framework/src/Volo.Abp.Core/System/AbpStringExtensions.cs
index 76ae06a5e0..f272484611 100644
--- a/framework/src/Volo.Abp.Core/System/AbpStringExtensions.cs
+++ b/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.
///
/// source string to be searched
- /// Char to search in
+ /// Char to search in
/// Count of the occurrence
public static int NthIndexOf(this string str, char c, int n)
{
diff --git a/framework/src/Volo.Abp.Core/System/Collections/Generic/AbpCollectionExtensions.cs b/framework/src/Volo.Abp.Core/System/Collections/Generic/AbpCollectionExtensions.cs
index e014ee9e21..f55bdd3bc8 100644
--- a/framework/src/Volo.Abp.Core/System/Collections/Generic/AbpCollectionExtensions.cs
+++ b/framework/src/Volo.Abp.Core/System/Collections/Generic/AbpCollectionExtensions.cs
@@ -107,7 +107,7 @@ namespace System.Collections.Generic
}
///
- /// Removes all items from the collection those satisfy the given .
+ /// Removes all items from the collection.
///
/// Type of the items in the collection
/// The collection
diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Reflection/TypeFinder.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Reflection/TypeFinder.cs
index 6576f08318..71ea895fd2 100644
--- a/framework/src/Volo.Abp.Core/Volo/Abp/Reflection/TypeFinder.cs
+++ b/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;
}
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Text/Formatting/FormattedStringValueExtracter.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Text/Formatting/FormattedStringValueExtracter.cs
index 6d21fc2a73..00d25681e4 100644
--- a/framework/src/Volo.Abp.Core/Volo/Abp/Text/Formatting/FormattedStringValueExtracter.cs
+++ b/framework/src/Volo.Abp.Core/Volo/Abp/Text/Formatting/FormattedStringValueExtracter.cs
@@ -11,7 +11,7 @@ namespace Volo.Abp.Text.Formatting
///
///
/// 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".
///
public class FormattedStringValueExtracter
{
@@ -84,7 +84,7 @@ namespace Volo.Abp.Text.Formatting
}
///
- /// Checks if given fits to given .
+ /// Checks if given fits to given .
/// Also gets extracted values.
///
/// String including dynamic values
@@ -127,4 +127,4 @@ namespace Volo.Abp.Text.Formatting
}
}
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.Dapper/Volo/Abp/Domain/Repositories/Dapper/DapperRepository.cs b/framework/src/Volo.Abp.Dapper/Volo/Abp/Domain/Repositories/Dapper/DapperRepository.cs
index cdb03f8515..39b3eed249 100644
--- a/framework/src/Volo.Abp.Dapper/Volo/Abp/Domain/Repositories/Dapper/DapperRepository.cs
+++ b/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 GetDbConnectionAsync() => (await _dbContextProvider.GetDbContextAsync()).Database.GetDbConnection();
+
+ [Obsolete("Use GetDbTransactionAsync method.")]
public IDbTransaction DbTransaction => _dbContextProvider.GetDbContext().Database.CurrentTransaction?.GetDbTransaction();
+
+ public async Task GetDbTransactionAsync() => (await _dbContextProvider.GetDbContextAsync()).Database.CurrentTransaction?.GetDbTransaction();
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.Dapper/Volo/Abp/Domain/Repositories/Dapper/IDapperRepository.cs b/framework/src/Volo.Abp.Dapper/Volo/Abp/Domain/Repositories/Dapper/IDapperRepository.cs
index f45be08b54..8145c646a0 100644
--- a/framework/src/Volo.Abp.Dapper/Volo/Abp/Domain/Repositories/Dapper/IDapperRepository.cs
+++ b/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 GetDbConnectionAsync();
+
+ [Obsolete("Use GetDbTransactionAsync method.")]
IDbTransaction DbTransaction { get; }
+
+ Task GetDbTransactionAsync();
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeedContext.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeedContext.cs
index 6cda2f6e39..6c470312d8 100644
--- a/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeedContext.cs
+++ b/framework/src/Volo.Abp.Data/Volo/Abp/Data/DataSeedContext.cs
@@ -13,8 +13,8 @@ namespace Volo.Abp.Data
///
/// Name of the property
///
- /// Returns the value in the dictionary by given .
- /// Returns null if given is not present in the dictionary.
+ /// Returns the value in the dictionary by given .
+ /// Returns null if given is not present in the dictionary.
///
[CanBeNull]
public object this[string name]
@@ -45,4 +45,4 @@ namespace Volo.Abp.Data
return this;
}
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/DefaultConnectionStringResolver.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/DefaultConnectionStringResolver.cs
index 84221fb271..4d5ce2fb27 100644
--- a/framework/src/Volo.Abp.Data/Volo/Abp/Data/DefaultConnectionStringResolver.cs
+++ b/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 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;
}
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/IConnectionStringResolver.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/IConnectionStringResolver.cs
index e9344ef66a..3bc8e22d78 100644
--- a/framework/src/Volo.Abp.Data/Volo/Abp/Data/IConnectionStringResolver.cs
+++ b/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 ResolveAsync(string connectionStringName = null);
}
}
diff --git a/framework/src/Volo.Abp.Data/Volo/Abp/Data/IConnectionStringResolverExtensions.cs b/framework/src/Volo.Abp.Data/Volo/Abp/Data/IConnectionStringResolverExtensions.cs
index e3a89e24e8..1fa097964c 100644
--- a/framework/src/Volo.Abp.Data/Volo/Abp/Data/IConnectionStringResolverExtensions.cs
+++ b/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(this IConnectionStringResolver resolver)
{
return resolver.Resolve(ConnectionStringNameAttribute.GetConnStringName());
}
+
+ [NotNull]
+ public static Task ResolveAsync(this IConnectionStringResolver resolver)
+ {
+ return resolver.ResolveAsync(ConnectionStringNameAttribute.GetConnStringName());
+ }
}
}
diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyCrudAppService.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyCrudAppService.cs
index 91879f030e..0cfb8ceb24 100644
--- a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyCrudAppService.cs
+++ b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyCrudAppService.cs
@@ -132,7 +132,7 @@ namespace Volo.Abp.Application.Services
}
///
- /// Maps to to create a new entity.
+ /// Maps to to create a new entity.
/// It uses by default.
/// It can be overriden for custom mapping.
/// Overriding this has higher priority than overriding the
@@ -143,7 +143,7 @@ namespace Volo.Abp.Application.Services
}
///
- /// Maps to to create a new entity.
+ /// Maps to to create a new entity.
/// It uses by default.
/// It can be overriden for custom mapping.
///
@@ -155,7 +155,7 @@ namespace Volo.Abp.Application.Services
}
///
- /// Sets Id value for the entity if is .
+ /// Sets Id value for the entity if is .
/// It's used while creating a new entity.
///
protected virtual void SetIdForGuids(TEntity entity)
@@ -171,7 +171,7 @@ namespace Volo.Abp.Application.Services
}
///
- /// Maps to to update the entity.
+ /// Maps to to update the entity.
/// It uses by default.
/// It can be overriden for custom mapping.
/// Overriding this has higher priority than overriding the
@@ -183,7 +183,7 @@ namespace Volo.Abp.Application.Services
}
///
- /// Maps to to update the entity.
+ /// Maps to to update the entity.
/// It uses by default.
/// It can be overriden for custom mapping.
///
diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyReadOnlyAppService.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyReadOnlyAppService.cs
index b9ffe3359b..54123bc843 100644
--- a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/AbstractKeyReadOnlyAppService.cs
+++ b/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.
///
/// The input.
+ [Obsolete("Override the CreateFilteredQueryAsync method instead.")]
protected virtual IQueryable CreateFilteredQuery(TGetListInput input)
{
return ReadOnlyRepository;
}
///
- /// Maps to .
+ /// This method should create based on given input.
+ /// It should filter query if needed, but should not do sorting or paging.
+ /// Sorting should be done in and paging should be done in
+ /// methods.
+ ///
+ /// The input.
+ protected virtual async Task> 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();
+ }
+
+ ///
+ /// Maps to .
/// It internally calls the by default.
/// It can be overriden for custom mapping.
/// Overriding this has higher priority than overriding the
@@ -177,7 +201,7 @@ namespace Volo.Abp.Application.Services
}
///
- /// Maps to .
+ /// Maps to .
/// It uses by default.
/// It can be overriden for custom mapping.
///
@@ -187,7 +211,7 @@ namespace Volo.Abp.Application.Services
}
///
- /// Maps a list of to objects.
+ /// Maps a list of to objects.
/// It uses method for each item in the list.
///
protected virtual async Task> MapToGetListOutputDtosAsync(List entities)
@@ -203,7 +227,7 @@ namespace Volo.Abp.Application.Services
}
///
- /// Maps to .
+ /// Maps to .
/// It internally calls the by default.
/// It can be overriden for custom mapping.
/// Overriding this has higher priority than overriding the
@@ -214,7 +238,7 @@ namespace Volo.Abp.Application.Services
}
///
- /// Maps to .
+ /// Maps to .
/// It uses by default.
/// It can be overriden for custom mapping.
///
diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/CrudAppService.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/CrudAppService.cs
index 111359d7f3..fffde41ba7 100644
--- a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/CrudAppService.cs
+++ b/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 GetEntityByIdAsync(TKey id)
+ protected override async Task GetEntityByIdAsync(TKey id)
{
return await Repository.GetAsync(id);
}
diff --git a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ReadOnlyAppService.cs b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ReadOnlyAppService.cs
index c585b2ac38..da3f386fd9 100644
--- a/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ReadOnlyAppService.cs
+++ b/framework/src/Volo.Abp.Ddd.Application/Volo/Abp/Application/Services/ReadOnlyAppService.cs
@@ -38,7 +38,7 @@ namespace Volo.Abp.Application.Services
where TGetOutputDto : IEntityDto
where TGetListOutputDto : IEntityDto
{
- protected new IReadOnlyRepository Repository { get; }
+ protected IReadOnlyRepository Repository { get; }
protected ReadOnlyAppService(IReadOnlyRepository repository)
: base(repository)
@@ -46,7 +46,7 @@ namespace Volo.Abp.Application.Services
Repository = repository;
}
- protected async override Task GetEntityByIdAsync(TKey id)
+ protected override async Task GetEntityByIdAsync(TKey id)
{
return await Repository.GetAsync(id);
}
diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/IAbpCommonDbContextRegistrationOptionsBuilder.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/IAbpCommonDbContextRegistrationOptionsBuilder.cs
index 368fa2dc96..53d2f142cd 100644
--- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/IAbpCommonDbContextRegistrationOptionsBuilder.cs
+++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/DependencyInjection/IAbpCommonDbContextRegistrationOptionsBuilder.cs
@@ -9,11 +9,11 @@ namespace Volo.Abp.DependencyInjection
IServiceCollection Services { get; }
///
- /// Registers default repositories for this DbContext.
+ /// Registers default repositories for this DbContext.
///
///
/// Registers repositories only for aggregate root entities by default.
- /// set to true to include all entities.
+ /// set to true to include all entities.
///
IAbpCommonDbContextRegistrationOptionsBuilder AddDefaultRepositories(bool includeAllEntities = false);
@@ -67,4 +67,4 @@ namespace Volo.Abp.DependencyInjection
/// The DbContext type to be replaced
IAbpCommonDbContextRegistrationOptionsBuilder ReplaceDbContext(Type otherDbContextType);
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IReadOnlyRepository.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IReadOnlyRepository.cs
index 499a1e58be..80d1425044 100644
--- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IReadOnlyRepository.cs
+++ b/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 WithDetails();
+ [Obsolete("Use WithDetailsAsync method.")]
IQueryable WithDetails(params Expression>[] propertySelectors);
+
+ Task> WithDetailsAsync(); //TODO: CancellationToken
+
+ Task> WithDetailsAsync(params Expression>[] propertySelectors); //TODO: CancellationToken
+
+ Task> GetQueryableAsync(); //TODO: CancellationToken
}
public interface IReadOnlyRepository : IReadOnlyRepository, IReadOnlyBasicRepository
diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryBase.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryBase.cs
index db0ec2b11c..8781fd9547 100644
--- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/RepositoryBase.cs
+++ b/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 : BasicRepositoryBase, IRepository, 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 WithDetails()
{
return GetQueryable();
}
+ [Obsolete("Use WithDetailsAsync method.")]
public virtual IQueryable WithDetails(params Expression>[] propertySelectors)
{
return GetQueryable();
}
+ public virtual Task> WithDetailsAsync()
+ {
+ return GetQueryableAsync();
+ }
+
+ public virtual Task> WithDetailsAsync(params Expression>[] 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 GetEnumerator()
{
return GetQueryable().GetEnumerator();
}
+ [Obsolete("Use GetQueryableAsync method.")]
protected abstract IQueryable GetQueryable();
+ public abstract Task> GetQueryableAsync();
+
public abstract Task FindAsync(
Expression> predicate,
bool includeDetails = true,
@@ -103,8 +123,6 @@ namespace Volo.Abp.Domain.Repositories
await DeleteAsync(entity, autoSave, cancellationToken);
}
-
-
public async Task DeleteManyAsync([NotNull] IEnumerable ids, bool autoSave = false, CancellationToken cancellationToken = default)
{
foreach (var id in ids)
diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EfCoreRepositoryExtensions.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EfCoreRepositoryExtensions.cs
index 2463062cde..5049a1b61b 100644
--- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EfCoreRepositoryExtensions.cs
+++ b/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(this IReadOnlyBasicRepository repository)
where TEntity : class, IEntity
{
return repository.ToEfCoreRepository().DbContext;
}
+ public static Task GetDbContextAsync(this IReadOnlyBasicRepository repository)
+ where TEntity : class, IEntity
+ {
+ return repository.ToEfCoreRepository().GetDbContextAsync();
+ }
+
+ [Obsolete("Use GetDbSetAsync method.")]
public static DbSet GetDbSet(this IReadOnlyBasicRepository repository)
where TEntity : class, IEntity
{
return repository.ToEfCoreRepository().DbSet;
}
+ public static Task> GetDbSetAsync(this IReadOnlyBasicRepository repository)
+ where TEntity : class, IEntity
+ {
+ return repository.ToEfCoreRepository().GetDbSetAsync();
+ }
+
public static IEfCoreRepository ToEfCoreRepository(this IReadOnlyBasicRepository repository)
where TEntity : class, IEntity
{
diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs
index ca885bd4fb..a95ec00e34 100644
--- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/EfCoreRepository.cs
+++ b/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 DbSet => DbContext.Set();
+ [Obsolete("Use GetDbContextAsync() method.")]
+ protected virtual TDbContext DbContext => _dbContextProvider.GetDbContext();
+ [Obsolete("Use GetDbContextAsync() method.")]
DbContext IEfCoreRepository.DbContext => DbContext.As();
- protected virtual TDbContext DbContext => _dbContextProvider.GetDbContext();
+ async Task IEfCoreRepository.GetDbContextAsync()
+ {
+ return await GetDbContextAsync() as DbContext;
+ }
+
+ protected virtual Task GetDbContextAsync()
+ {
+ return _dbContextProvider.GetDbContextAsync();
+ }
+
+ [Obsolete("Use GetDbSetAsync() method.")]
+ public virtual DbSet DbSet => DbContext.Set();
+
+ Task> IEfCoreRepository.GetDbSetAsync()
+ {
+ return GetDbSetAsync();
+ }
+
+ protected async Task> GetDbSetAsync()
+ {
+ return (await GetDbContextAsync()).Set();
+ }
protected virtual AbpEntityOptions AbpEntityOptions => _entityOptionsLazy.Value;
private readonly IDbContextProvider _dbContextProvider;
private readonly Lazy> _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 InsertAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
+ public override async Task 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().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 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(
this,
- entities,
+ entityArray,
autoSave,
cancellationToken
);
return;
}
- await DbSet.AddRangeAsync(entities);
+ await dbContext.Set().AddRangeAsync(entityArray, cancellationToken);
if (autoSave)
{
- await DbContext.SaveChangesAsync();
+ await dbContext.SaveChangesAsync(cancellationToken);
}
}
- public async override Task UpdateAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
+ public override async Task 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 entities, bool autoSave = false, CancellationToken cancellationToken = default)
{
+ cancellationToken = GetCancellationToken(cancellationToken);
+
if (BulkOperationProvider != null)
{
await BulkOperationProvider.UpdateManyAsync(
@@ -117,65 +148,76 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
return;
}
- DbSet.UpdateRange(entities);
+ var dbContext = await GetDbContextAsync();
+
+ dbContext.Set().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().Remove(entity);
if (autoSave)
{
- await DbContext.SaveChangesAsync(GetCancellationToken(cancellationToken));
+ await dbContext.SaveChangesAsync(GetCancellationToken(cancellationToken));
}
}
public override async Task DeleteManyAsync(IEnumerable entities, bool autoSave = false, CancellationToken cancellationToken = default)
{
+ cancellationToken = GetCancellationToken(cancellationToken);
+
if (BulkOperationProvider != null)
{
await BulkOperationProvider.DeleteManyAsync(
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> GetListAsync(bool includeDetails = false, CancellationToken cancellationToken = default)
+ public override async Task> 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 GetCountAsync(CancellationToken cancellationToken = default)
+ public override async Task GetCountAsync(CancellationToken cancellationToken = default)
{
- return await DbSet.LongCountAsync(GetCancellationToken(cancellationToken));
+ return await (await GetDbSetAsync()).LongCountAsync(GetCancellationToken(cancellationToken));
}
- public async override Task> GetPagedListAsync(
+ public override async Task> 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 GetQueryable()
{
return DbSet.AsQueryable();
}
- protected override Task SaveChangesAsync(CancellationToken cancellationToken)
+ public override async Task> 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 FindAsync(
+ public override async Task FindAsync(
Expression> 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> predicate, bool autoSave = false, CancellationToken cancellationToken = default)
+ public override async Task DeleteAsync(Expression> predicate, bool autoSave = false, CancellationToken cancellationToken = default)
{
- var entities = await GetQueryable()
+ var dbContext = await GetDbContextAsync();
+ var dbSet = dbContext.Set();
+
+ 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 WithDetails()
{
if (AbpEntityOptions.DefaultWithDetailsFunc == null)
@@ -258,10 +310,37 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
return AbpEntityOptions.DefaultWithDetailsFunc(GetQueryable());
}
+ public override async Task> WithDetailsAsync()
+ {
+ if (AbpEntityOptions.DefaultWithDetailsFunc == null)
+ {
+ return await base.WithDetailsAsync();
+ }
+
+ return AbpEntityOptions.DefaultWithDetailsFunc(await GetQueryableAsync());
+ }
+
+ [Obsolete("Use WithDetailsAsync method.")]
public override IQueryable WithDetails(params Expression>[] propertySelectors)
{
- var query = GetQueryable();
+ return IncludeDetails(
+ GetQueryable(),
+ propertySelectors
+ );
+ }
+ public override async Task> WithDetailsAsync(params Expression>[] propertySelectors)
+ {
+ return IncludeDetails(
+ await GetQueryableAsync(),
+ propertySelectors
+ );
+ }
+
+ private static IQueryable IncludeDetails(
+ IQueryable query,
+ Expression>[] 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 GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return DbSet.AsAsyncEnumerable().GetAsyncEnumerator(cancellationToken);
@@ -329,8 +409,8 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
public virtual async Task 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 ids, bool autoSave = false, CancellationToken cancellationToken = default)
+ public virtual async Task DeleteManyAsync(IEnumerable 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);
}
diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/IEfCoreRepository.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/IEfCoreRepository.cs
index 31a78f744d..f793dc04ed 100644
--- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/IEfCoreRepository.cs
+++ b/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 : IRepository
where TEntity : class, IEntity
{
+ [Obsolete("Use GetDbContextAsync() method.")]
DbContext DbContext { get; }
+ [Obsolete("Use GetDbSetAsync() method.")]
DbSet DbSet { get; }
+
+ Task GetDbContextAsync();
+
+ Task> GetDbSetAsync();
}
public interface IEfCoreRepository : IEfCoreRepository, IRepository
@@ -16,4 +24,4 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore
{
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/DbContextOptionsFactory.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/DbContextOptionsFactory.cs
index a2d52eac48..0147de12fb 100644
--- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/DbContextOptionsFactory.cs
+++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/DependencyInjection/DbContextOptionsFactory.cs
@@ -86,7 +86,11 @@ namespace Volo.Abp.EntityFrameworkCore.DependencyInjection
}
var connectionStringName = ConnectionStringNameAttribute.GetConnStringName();
+
+ //Use DefaultConnectionStringResolver.Resolve when we remove IConnectionStringResolver.Resolve
+#pragma warning disable 618
var connectionString = serviceProvider.GetRequiredService().Resolve(connectionStringName);
+#pragma warning restore 618
return new DbContextCreationContext(
connectionStringName,
diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/EfCoreAsyncQueryableProvider.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/EfCoreAsyncQueryableProvider.cs
index 68ff261588..2a0400c578 100644
--- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/EfCoreAsyncQueryableProvider.cs
+++ b/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(IQueryable queryable)
{
diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/IDbContextProvider.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/IDbContextProvider.cs
index c4655fddd0..b35436cfbc 100644
--- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/IDbContextProvider.cs
+++ b/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
+ public interface IDbContextProvider
where TDbContext : IEfCoreDbContext
{
+ [Obsolete("Use GetDbContextAsync method.")]
TDbContext GetDbContext();
+
+ Task GetDbContextAsync();
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/ObjectExtending/EfCoreObjectExtensionManagerExtensions.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/ObjectExtending/EfCoreObjectExtensionManagerExtensions.cs
index 14fcc93784..54c1909bb3 100644
--- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/ObjectExtending/EfCoreObjectExtensionManagerExtensions.cs
+++ b/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
}
}
}
diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/UnitOfWorkDbContextProvider.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/UnitOfWorkDbContextProvider.cs
index 91ed2f8126..143a5659cc 100644
--- a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Uow/EntityFrameworkCore/UnitOfWorkDbContextProvider.cs
+++ b/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 : IDbContextProvider
where TDbContext : IEfCoreDbContext
{
+ public ILogger> 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>.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 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)databaseApi).DbContext;
}
+ public async Task 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();
+ var connectionString = await _connectionStringResolver.ResolveAsync(connectionStringName);
+
+ var dbContextKey = $"{typeof(TDbContext).FullName}_{connectionString}";
+
+ var databaseApi = unitOfWork.FindDatabaseApi(dbContextKey);
+
+ if (databaseApi == null)
+ {
+ databaseApi = new EfCoreDatabaseApi(
+ await CreateDbContextAsync(unitOfWork, connectionStringName, connectionString)
+ );
+
+ unitOfWork.AddDatabaseApi(dbContextKey, databaseApi);
+ }
+
+ return ((EfCoreDatabaseApi)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 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();
}
- public TDbContext CreateDbContextWithTransaction(IUnitOfWork unitOfWork)
+ private async Task CreateDbContextAsync(IUnitOfWork unitOfWork)
+ {
+ Logger.LogDebug($"Creating a new DbContext of type {typeof(TDbContext).FullName}");
+
+ return unitOfWork.Options.IsTransactional
+ ? await CreateDbContextWithTransactionAsync(unitOfWork)
+ : unitOfWork.ServiceProvider.GetRequiredService();
+ }
+
+ 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 CreateDbContextWithTransactionAsync(IUnitOfWork unitOfWork)
+ {
+ var transactionApiKey = $"EntityFrameworkCore_{DbContextCreationContext.Current.ConnectionString}";
+ var activeTransaction = unitOfWork.FindTransactionApi(transactionApiKey) as EfCoreTransactionApi;
+
+ if (activeTransaction == null)
+ {
+ var dbContext = unitOfWork.ServiceProvider.GetRequiredService();
+
+ 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();
+
+ if (dbContext.As().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);
+ }
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventBus.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventBus.cs
index 1d93c05580..d28b3ab2a4 100644
--- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventBus.cs
+++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventBus.cs
@@ -33,7 +33,7 @@ namespace Volo.Abp.EventBus
///
/// Registers to an event.
- /// A new instance of object is created for every event occurrence.
+ /// A new instance of object is created for every event occurrence.
///
/// Event type
/// Type of the event handler
@@ -116,4 +116,4 @@ namespace Volo.Abp.EventBus
/// Event type
void UnsubscribeAll(Type eventType);
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventDataMayHaveTenantId.cs b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventDataMayHaveTenantId.cs
index 72a8c753cd..9ff8b89cd8 100644
--- a/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventDataMayHaveTenantId.cs
+++ b/framework/src/Volo.Abp.EventBus/Volo/Abp/EventBus/IEventDataMayHaveTenantId.cs
@@ -16,8 +16,8 @@ namespace Volo.Abp.EventBus
{
///
/// Returns true if this event data has a Tenant Id information.
- /// If so, it should set the our parameter.
- /// Otherwise, the our parameter value should not be informative
+ /// If so, it should set the our parameter.
+ /// Otherwise, the our parameter value should not be informative
/// (it will be null as expected, but doesn't indicate a tenant with null tenant id).
///
///
diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureDefinition.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureDefinition.cs
index b2b11f0a18..609f42acd2 100644
--- a/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureDefinition.cs
+++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureDefinition.cs
@@ -69,8 +69,8 @@ namespace Volo.Abp.Features
///
/// Name of the property
///
- /// Returns the value in the dictionary by given .
- /// Returns null if given is not present in the dictionary.
+ /// Returns the value in the dictionary by given .
+ /// Returns null if given is not present in the dictionary.
///
[CanBeNull]
public object this[string name]
diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureGroupDefinition.cs b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureGroupDefinition.cs
index cba38070a7..b4dd98eb5b 100644
--- a/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureGroupDefinition.cs
+++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureGroupDefinition.cs
@@ -29,8 +29,8 @@ namespace Volo.Abp.Features
///
/// Name of the property
///
- /// Returns the value in the dictionary by given .
- /// Returns null if given is not present in the dictionary.
+ /// Returns the value in the dictionary by given .
+ /// Returns null if given is not present in the dictionary.
///
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}]";
}
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/IMemoryDbRepository.cs b/framework/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/IMemoryDbRepository.cs
index c179b68931..6d4fb7d896 100644
--- a/framework/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/IMemoryDbRepository.cs
+++ b/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 : IRepository
where TEntity : class, IEntity
{
+ [Obsolete("Use GetDatabaseAsync() method.")]
IMemoryDatabase Database { get; }
+ [Obsolete("Use GetCollectionAsync() method.")]
IMemoryDatabaseCollection Collection { get; }
+
+ Task GetDatabaseAsync();
+
+ Task> GetCollectionAsync();
}
public interface IMemoryDbRepository : IMemoryDbRepository, IRepository
diff --git a/framework/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDbRepository.cs b/framework/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDbRepository.cs
index 7c67e254ee..811c51ed5f 100644
--- a/framework/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDb/MemoryDbRepository.cs
+++ b/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 Collection => Database.Collection();
+ public async Task> GetCollectionAsync()
+ {
+ return (await GetDatabaseAsync()).Collection();
+ }
+
+ [Obsolete("Use GetDatabaseAsync method.")]
public virtual IMemoryDatabase Database => DatabaseProvider.GetDatabase();
+ public Task GetDatabaseAsync()
+ {
+ return DatabaseProvider.GetDatabaseAsync();
+ }
+
protected IMemoryDatabaseProvider 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 GetQueryable()
{
return ApplyDataFilters(Collection.AsQueryable());
}
+ public override async Task> 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 FindAsync(
+ public override async Task FindAsync(
Expression> 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> 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 InsertAsync(
+ public override async Task 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 UpdateAsync(
+ public override async Task 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> GetListAsync(bool includeDetails = false, CancellationToken cancellationToken = default)
+ public override async Task> GetListAsync(bool includeDetails = false, CancellationToken cancellationToken = default)
{
- return Task.FromResult(GetQueryable().ToList());
+ return (await GetQueryableAsync()).ToList();
}
- public override Task GetCountAsync(CancellationToken cancellationToken = default)
+ public override async Task GetCountAsync(CancellationToken cancellationToken = default)
{
- return Task.FromResult(GetQueryable().LongCount());
+ return (await GetQueryableAsync()).LongCount();
}
- public override Task> GetPagedListAsync(
+ public override async Task> 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 InsertAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
+ public override async Task 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());
+ var nextId = (await GetDatabaseAsync()).GenerateNextId();
+ EntityHelper.TrySetId(entity, () => nextId);
}
}
}
@@ -301,9 +320,9 @@ namespace Volo.Abp.Domain.Repositories.MemoryDb
return entity;
}
- public virtual Task FindAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default)
+ public virtual async Task 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 ids, bool autoSave = false, CancellationToken cancellationToken = default)
+ public virtual async Task DeleteManyAsync(IEnumerable 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);
}
}
}
diff --git a/framework/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDbCoreRepositoryExtensions.cs b/framework/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDbCoreRepositoryExtensions.cs
index 1547a581e5..003bf8b034 100644
--- a/framework/src/Volo.Abp.MemoryDb/Volo/Abp/Domain/Repositories/MemoryDbCoreRepositoryExtensions.cs
+++ b/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(this IBasicRepository repository)
where TEntity : class, IEntity
{
return repository.ToMemoryDbRepository().Database;
}
+ public static Task GetDatabaseAsync(this IBasicRepository repository)
+ where TEntity : class, IEntity
+ {
+ return repository.ToMemoryDbRepository().GetDatabaseAsync();
+ }
+
+ [Obsolete("Use GetCollectionAsync method.")]
public static IMemoryDatabaseCollection GetCollection(this IBasicRepository repository)
where TEntity : class, IEntity
{
return repository.ToMemoryDbRepository().Collection;
}
+ public static Task> GetCollectionAsync(this IBasicRepository repository)
+ where TEntity : class, IEntity
+ {
+ return repository.ToMemoryDbRepository().GetCollectionAsync();
+ }
+
public static IMemoryDbRepository ToMemoryDbRepository(this IBasicRepository repository)
where TEntity : class, IEntity
{
@@ -31,4 +46,4 @@ namespace Volo.Abp.Domain.Repositories
return memoryDbRepository;
}
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/IMemoryDatabaseProvider.cs b/framework/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/IMemoryDatabaseProvider.cs
index ad4456c793..514b079e69 100644
--- a/framework/src/Volo.Abp.MemoryDb/Volo/Abp/MemoryDb/IMemoryDatabaseProvider.cs
+++ b/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
where TMemoryDbContext : MemoryDbContext
{
+ [Obsolete("Use GetDbContextAsync method.")]
TMemoryDbContext DbContext { get; }
+ Task GetDbContextAsync();
+
+ [Obsolete("Use GetDatabaseAsync method.")]
IMemoryDatabase GetDatabase();
+
+ Task GetDatabaseAsync();
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.MemoryDb/Volo/Abp/Uow/MemoryDb/UnitOfWorkMemoryDatabaseProvider.cs b/framework/src/Volo.Abp.MemoryDb/Volo/Abp/Uow/MemoryDb/UnitOfWorkMemoryDatabaseProvider.cs
index 24c1cdaeb9..c2c5a1df71 100644
--- a/framework/src/Volo.Abp.MemoryDb/Volo/Abp/Uow/MemoryDb/UnitOfWorkMemoryDatabaseProvider.cs
+++ b/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 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 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();
+ var dbContextKey = $"{typeof(TMemoryDbContext).FullName}_{connectionString}";
+
+ var databaseApi = unitOfWork.GetOrAddDatabaseApi(
+ dbContextKey,
+ () => new MemoryDbDatabaseApi(
+ _memoryDatabaseManager.Get(connectionString)
+ ));
+
+ return ((MemoryDbDatabaseApi)databaseApi).Database;
+ }
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/IMongoDbRepository.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/IMongoDbRepository.cs
index 50155c6df5..960222679f 100644
--- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/IMongoDbRepository.cs
+++ b/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 : IRepository
where TEntity : class, IEntity
{
+ [Obsolete("Use GetDatabaseAsync method.")]
IMongoDatabase Database { get; }
+ Task GetDatabaseAsync(CancellationToken cancellationToken = default);
+
+ [Obsolete("Use GetCollectionAsync method.")]
IMongoCollection Collection { get; }
+ Task> GetCollectionAsync(CancellationToken cancellationToken = default);
+
+ [Obsolete("Use GetMongoQueryableAsync method.")]
IMongoQueryable GetMongoQueryable();
+
+ Task> GetMongoQueryableAsync(CancellationToken cancellationToken = default);
}
public interface IMongoDbRepository : IMongoDbRepository, IRepository
diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs
index 109aeac8cd..53c291a178 100644
--- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs
+++ b/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 Collection => DbContext.Collection();
+ public async Task> GetCollectionAsync(CancellationToken cancellationToken = default)
+ {
+ return (await GetDbContextAsync(GetCancellationToken(cancellationToken))).Collection();
+ }
+
+ [Obsolete("Use GetDatabaseAsync method.")]
public virtual IMongoDatabase Database => DbContext.Database;
- public virtual IClientSessionHandle SessionHandle => DbContext.SessionHandle;
+ public async Task 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 GetSessionHandleAsync(CancellationToken cancellationToken = default)
+ {
+ return (await GetDbContextAsync(GetCancellationToken(cancellationToken))).SessionHandle;
+ }
+
+ [Obsolete("Use GetDbContextAsync method.")]
+ protected virtual TMongoDbContext DbContext => DbContextProvider.GetDbContext();
+
+ protected Task GetDbContextAsync(CancellationToken cancellationToken = default)
+ {
+ return DbContextProvider.GetDbContextAsync(GetCancellationToken(cancellationToken));
+ }
protected IMongoDbContextProvider DbContextProvider { get; }
@@ -59,24 +83,27 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
GuidGenerator = SimpleGuidGenerator.Instance;
}
- public async override Task InsertAsync(
+ public override async Task 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();
+
+ 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 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();
+
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 UpdateAsync(
+ public override async Task 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();
+
+ 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 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> replaceRequests = new List>();
- foreach (var entity in entities)
+ foreach (var entity in entityArray)
{
replaceRequests.Add(new ReplaceOneModel(CreateEntityFilter(entity), entity));
}
- if (SessionHandle != null)
+ var collection = dbContext.Collection();
+ 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();
+
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();
+
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.Update.Set(x => ((ISoftDelete)x).IsDeleted, true)
);
}
else
{
- updateResult = await Collection.UpdateManyAsync(
- CreateEntitiesFilter(entities),
+ updateResult = await collection.UpdateManyAsync(
+ CreateEntitiesFilter(entityArray),
Builders.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> GetListAsync(bool includeDetails = false, CancellationToken cancellationToken = default)
+ public override async Task> 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 GetCountAsync(CancellationToken cancellationToken = default)
+ public override async Task GetCountAsync(CancellationToken cancellationToken = default)
{
- return await GetMongoQueryable().LongCountAsync(GetCancellationToken(cancellationToken));
+ cancellationToken = GetCancellationToken(cancellationToken);
+ return await (await GetMongoQueryableAsync(cancellationToken)).LongCountAsync(cancellationToken);
}
- public async override Task> GetPagedListAsync(
+ public override async Task> 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>()
.PageBy>(skipCount, maxResultCount)
- .ToListAsync(GetCancellationToken(cancellationToken));
+ .ToListAsync(cancellationToken);
}
- public async override Task DeleteAsync(
+ public override async Task DeleteAsync(
Expression> 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 GetQueryable()
{
return GetMongoQueryable();
}
- public async override Task FindAsync(
+ public override async Task> GetQueryableAsync()
+ {
+ return await GetMongoQueryableAsync();
+ }
+
+ public override async Task FindAsync(
Expression> 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 GetMongoQueryable()
{
- return ApplyDataFilters(SessionHandle != null ? Collection.AsQueryable(SessionHandle) : Collection.AsQueryable());
+ return ApplyDataFilters(
+ SessionHandle != null
+ ? Collection.AsQueryable(SessionHandle)
+ : Collection.AsQueryable()
+ );
+ }
+
+ public async Task> GetMongoQueryableAsync(CancellationToken cancellationToken = default)
+ {
+ var dbContext = await GetDbContextAsync(cancellationToken);
+ var collection = dbContext.Collection();
+
+ 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;
@@ -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.");
}
- ///
- /// IMongoQueryable
- ///
- ///
+ [Obsolete("This method will be removed in future versions.")]
public QueryableExecutionModel GetExecutionModel()
{
return GetMongoQueryable().GetExecutionModel();
}
- ///
- /// IMongoQueryable
- ///
- ///
- ///
+ [Obsolete("This method will be removed in future versions.")]
public IAsyncCursor ToCursor(CancellationToken cancellationToken = new CancellationToken())
{
return GetMongoQueryable().ToCursor(cancellationToken);
}
- ///
- /// IMongoQueryable
- ///
- ///
- ///
+ [Obsolete("This method will be removed in future versions.")]
public Task> 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();
+
+ 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 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);
}
diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDbCoreRepositoryExtensions.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDbCoreRepositoryExtensions.cs
index 12da0afaa2..ff367dc554 100644
--- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDbCoreRepositoryExtensions.cs
+++ b/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(this IBasicRepository repository)
where TEntity : class, IEntity
{
return repository.ToMongoDbRepository().Database;
}
+ public static Task GetDatabaseAsync(this IBasicRepository repository)
+ where TEntity : class, IEntity
+ {
+ return repository.ToMongoDbRepository().GetDatabaseAsync();
+ }
+
+ [Obsolete("Use GetCollection method.")]
public static IMongoCollection GetCollection(this IBasicRepository repository)
where TEntity : class, IEntity
{
return repository.ToMongoDbRepository().Collection;
}
+ public static Task> GetCollectionAsync(this IBasicRepository repository)
+ where TEntity : class, IEntity
+ {
+ return repository.ToMongoDbRepository().GetCollectionAsync();
+ }
+
+ [Obsolete("Use GetMongoQueryableAsync method.")]
public static IMongoQueryable GetMongoQueryable(this IBasicRepository repository)
where TEntity : class, IEntity
{
return repository.ToMongoDbRepository().GetMongoQueryable();
}
+ public static Task> GetMongoQueryableAsync(this IBasicRepository repository)
+ where TEntity : class, IEntity
+ {
+ return repository.ToMongoDbRepository().GetMongoQueryableAsync();
+ }
+
public static IMongoDbRepository ToMongoDbRepository(this IBasicRepository repository)
where TEntity : class, IEntity
{
@@ -38,4 +60,4 @@ namespace Volo.Abp.Domain.Repositories
return mongoDbRepository;
}
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/IMongoDbContextProvider.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/IMongoDbContextProvider.cs
index 9f89054dcc..959cb39df1 100644
--- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/IMongoDbContextProvider.cs
+++ b/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
+ public interface IMongoDbContextProvider
where TMongoDbContext : IAbpMongoDbContext
{
+ [Obsolete("Use CreateDbContextAsync")]
TMongoDbContext GetDbContext();
+
+ Task GetDbContextAsync(CancellationToken cancellationToken = default);
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/MongoDbAsyncQueryableProvider.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/MongoDbAsyncQueryableProvider.cs
index a8dc34e83a..52c5edd1d3 100644
--- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/MongoDbAsyncQueryableProvider.cs
+++ b/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(IQueryable queryable)
{
diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs
index d3d8a419fb..724e7673fc 100644
--- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Uow/MongoDB/UnitOfWorkMongoDbContextProvider.cs
+++ b/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 : IMongoDbContextProvider
where TMongoDbContext : IAbpMongoDbContext
{
+ public ILogger> 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>.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 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) databaseApi).DbContext;
}
+ public async Task 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();
+ var dbContextKey = $"{typeof(TMongoDbContext).FullName}_{connectionString}";
+
+ var mongoUrl = new MongoUrl(connectionString);
+ var databaseName = mongoUrl.DatabaseName;
+ if (databaseName.IsNullOrWhiteSpace())
+ {
+ databaseName = ConnectionStringNameAttribute.GetConnStringName();
+ }
+
+ //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(
+ await CreateDbContextAsync(
+ unitOfWork,
+ mongoUrl,
+ databaseName,
+ cancellationToken
+ )
+ );
+
+ unitOfWork.AddDatabaseApi(dbContextKey, databaseApi);
+ }
+
+ return ((MongoDbDatabaseApi) 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 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();
+ 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 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();
+
+ 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);
+ }
}
}
diff --git a/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ITenantStore.cs b/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ITenantStore.cs
index 7125a97405..6c66044e37 100644
--- a/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ITenantStore.cs
+++ b/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ITenantStore.cs
@@ -9,8 +9,10 @@ namespace Volo.Abp.MultiTenancy
Task FindAsync(Guid id);
+ [Obsolete("Use FindAsync method.")]
TenantConfiguration Find(string name);
+ [Obsolete("Use FindAsync method.")]
TenantConfiguration Find(Guid id);
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/MultiTenantConnectionStringResolver.cs b/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/MultiTenantConnectionStringResolver.cs
index d92409fe0d..0d82419013 100644
--- a/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/MultiTenantConnectionStringResolver.cs
+++ b/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 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();
+
+ 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
diff --git a/framework/src/Volo.Abp.Threading/Volo/Abp/Linq/AsyncQueryableExecuter.cs b/framework/src/Volo.Abp.Threading/Volo/Abp/Linq/AsyncQueryableExecuter.cs
index f5b3cf3a6d..b7ac83dc5f 100644
--- a/framework/src/Volo.Abp.Threading/Volo/Abp/Linq/AsyncQueryableExecuter.cs
+++ b/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 Providers { get; }
diff --git a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/IUnitOfWorkTransactionBehaviourProvider.cs b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/IUnitOfWorkTransactionBehaviourProvider.cs
new file mode 100644
index 0000000000..1db7dac938
--- /dev/null
+++ b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/IUnitOfWorkTransactionBehaviourProvider.cs
@@ -0,0 +1,7 @@
+namespace Volo.Abp.Uow
+{
+ public interface IUnitOfWorkTransactionBehaviourProvider
+ {
+ bool? IsTransactional { get; }
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/NullUnitOfWorkTransactionBehaviourProvider.cs b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/NullUnitOfWorkTransactionBehaviourProvider.cs
new file mode 100644
index 0000000000..2b302d303a
--- /dev/null
+++ b/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;
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWork.cs b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWork.cs
index b4158229fe..d53acc8f66 100644
--- a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWork.cs
+++ b/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())
diff --git a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkFailedEventArgs.cs b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkFailedEventArgs.cs
index df867c2320..ed225ccc58 100644
--- a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkFailedEventArgs.cs
+++ b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkFailedEventArgs.cs
@@ -9,8 +9,8 @@ namespace Volo.Abp.Uow
public class UnitOfWorkFailedEventArgs : UnitOfWorkEventArgs
{
///
- /// Exception that caused failure. This is set only if an error occurred during .
- /// Can be null if there is no exception, but is not called.
+ /// Exception that caused failure. This is set only if an error occurred during .
+ /// Can be null if there is no exception, but is not called.
/// Can be null if another exception occurred during the UOW.
///
[CanBeNull]
diff --git a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkInterceptor.cs b/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkInterceptor.cs
index f5afcea494..464b6bb871 100644
--- a/framework/src/Volo.Abp.Uow/Volo/Abp/Uow/UnitOfWorkInterceptor.cs
+++ b/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 options)
+ public UnitOfWorkInterceptor(
+ IUnitOfWorkManager unitOfWorkManager,
+ IOptions 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)
);
}
diff --git a/framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/Auditing_Tests.cs b/framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/Auditing_Tests.cs
index 8c647c92c4..8ca1228ee6 100644
--- a/framework/test/Volo.Abp.Auditing.Tests/Volo/Abp/Auditing/Auditing_Tests.cs
+++ b/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 DoItAsync(InputObject inputObject)
+ public virtual Task DoItAsync(InputObject inputObject)
{
- return new ResultObject
+ return Task.FromResult(new ResultObject
{
Value1 = inputObject.Value1 + "-result",
Value2 = inputObject.Value2 + 1
- };
+ });
}
}
diff --git a/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AbpAutoMapperModule_Basic_Tests.cs b/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AbpAutoMapperModule_Basic_Tests.cs
index 3ac2246dcc..ea70649350 100644
--- a/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AbpAutoMapperModule_Basic_Tests.cs
+++ b/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(() =>
{
_objectMapper.Map(new MyEntity {Number = 42});
});
- }
+ }*/
}
}
diff --git a/framework/test/Volo.Abp.Dapper.Tests/Volo/Abp/Dapper/Repositories/PersonDapperRepository.cs b/framework/test/Volo.Abp.Dapper.Tests/Volo/Abp/Dapper/Repositories/PersonDapperRepository.cs
index b5127e3d7e..e4510a366a 100644
--- a/framework/test/Volo.Abp.Dapper.Tests/Volo/Abp/Dapper/Repositories/PersonDapperRepository.cs
+++ b/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> GetAllPersonNames()
{
- return (await DbConnection.QueryAsync("select Name from People", transaction: DbTransaction))
- .ToList();
+ return (await (await GetDbConnectionAsync())
+ .QueryAsync(
+ "select Name from People",
+ transaction: await GetDbTransactionAsync()
+ )
+ ).ToList();
}
public virtual async Task 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());
}
}
-}
\ No newline at end of file
+}
diff --git a/framework/test/Volo.Abp.Data.Tests/Volo/Abp/Data/ConnectionStringResolver_Tests.cs b/framework/test/Volo.Abp.Data.Tests/Volo/Abp/Data/ConnectionStringResolver_Tests.cs
index d13c89671e..3971c29ff0 100644
--- a/framework/test/Volo.Abp.Data.Tests/Volo/Abp/Data/ConnectionStringResolver_Tests.cs
+++ b/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))]
diff --git a/framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Repositories/RepositoryRegistration_Tests.cs b/framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Repositories/RepositoryRegistration_Tests.cs
index baf49f4314..85696fae21 100644
--- a/framework/test/Volo.Abp.Ddd.Tests/Volo/Abp/Domain/Repositories/RepositoryRegistration_Tests.cs
+++ b/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 GetQueryable()
{
throw new NotImplementedException();
}
+ public override Task> GetQueryableAsync()
+ {
+ throw new NotImplementedException();
+ }
+
public override Task FindAsync(Expression> predicate, bool includeDetails = true, CancellationToken cancellationToken = default)
{
throw new NotImplementedException();
diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/DbContext_Replace_Tests.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/DbContext_Replace_Tests.cs
index 7bc4af2e31..977cb8522a 100644
--- a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/DbContext_Replace_Tests.cs
+++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/DbContext_Replace_Tests.cs
@@ -26,12 +26,12 @@ namespace Volo.Abp.EntityFrameworkCore
{
(ServiceProvider.GetRequiredService() 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();
}
}
}
diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Domain/ExtraProperties_Tests.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Domain/ExtraProperties_Tests.cs
index f94f16c390..aa1e0080b5 100644
--- a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/EntityFrameworkCore/Domain/ExtraProperties_Tests.cs
+++ b/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;
});
-
}
}
}
diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/CityRepository.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/CityRepository.cs
index 027f54a03a..cd85cbcb5a 100644
--- a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/CityRepository.cs
+++ b/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, ICityRepository
{
- public CityRepository(IDbContextProvider dbContextProvider)
+ public CityRepository(IDbContextProvider dbContextProvider)
: base(dbContextProvider)
{
}
@@ -24,7 +24,7 @@ namespace Volo.Abp.TestApp.EntityFrameworkCore
public async Task> 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();
}
}
}
diff --git a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/PersonRepository.cs b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/PersonRepository.cs
index ab8c1920a7..6413140bf1 100644
--- a/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/PersonRepository.cs
+++ b/framework/test/Volo.Abp.EntityFrameworkCore.Tests/Volo/Abp/TestApp/EntityFrameworkCore/PersonRepository.cs
@@ -18,7 +18,7 @@ namespace Volo.Abp.TestApp.EntityFrameworkCore
public async Task GetViewAsync(string name)
{
- return await DbContext.PersonView.Where(x => x.Name == name).FirstOrDefaultAsync();
+ return await (await GetDbContextAsync()).PersonView.Where(x => x.Name == name).FirstOrDefaultAsync();
}
}
-}
\ No newline at end of file
+}
diff --git a/framework/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/TestApp/MemoryDb/CityRepository.cs b/framework/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/TestApp/MemoryDb/CityRepository.cs
index b6d43dc875..309339e09d 100644
--- a/framework/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/TestApp/MemoryDb/CityRepository.cs
+++ b/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, ICityRepository
{
- public CityRepository(IMemoryDatabaseProvider databaseProvider)
+ public CityRepository(IMemoryDatabaseProvider databaseProvider)
: base(databaseProvider)
{
}
- public Task FindByNameAsync(string name)
+ public async Task FindByNameAsync(string name)
{
- return Task.FromResult(Collection.FirstOrDefault(c => c.Name == name));
+ return (await GetCollectionAsync()).FirstOrDefault(c => c.Name == name);
}
public async Task> GetPeopleInTheCityAsync(string cityName)
{
var city = await FindByNameAsync(cityName);
- return Database.Collection().Where(p => p.CityId == city.Id).ToList();
+ return (await GetDatabaseAsync()).Collection().Where(p => p.CityId == city.Id).ToList();
}
}
}
diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/MongoDbAsyncQueryableProvider_Tests.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/MongoDbAsyncQueryableProvider_Tests.cs
index ae9be03d57..5335aa11be 100644
--- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/MongoDbAsyncQueryableProvider_Tests.cs
+++ b/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]
diff --git a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/TestApp/MongoDb/CityRepository.cs b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/TestApp/MongoDb/CityRepository.cs
index bb31883010..df6eed85cc 100644
--- a/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/TestApp/MongoDb/CityRepository.cs
+++ b/framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/TestApp/MongoDb/CityRepository.cs
@@ -19,13 +19,13 @@ namespace Volo.Abp.TestApp.MongoDB
public async Task 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> 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();
}
}
}
diff --git a/framework/test/Volo.Abp.MultiTenancy.Tests/Volo/Abp/Data/MultiTenancy/MultiTenantConnectionStringResolver_Tests.cs b/framework/test/Volo.Abp.MultiTenancy.Tests/Volo/Abp/Data/MultiTenancy/MultiTenantConnectionStringResolver_Tests.cs
index a6e5fab1c8..f6af2bde72 100644
--- a/framework/test/Volo.Abp.MultiTenancy.Tests/Volo/Abp/Data/MultiTenancy/MultiTenantConnectionStringResolver_Tests.cs
+++ b/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");
}
}
}
diff --git a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/Repository_Queryable_Tests.cs b/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/Repository_Queryable_Tests.cs
index 6078236380..3ca511a7ea 100644
--- a/framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/Repository_Queryable_Tests.cs
+++ b/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;
});
}
}
diff --git a/framework/test/Volo.Abp.Uow.Tests/Volo/Abp/Uow/UnitOfWork_Events_Tests.cs b/framework/test/Volo.Abp.Uow.Tests/Volo/Abp/Uow/UnitOfWork_Events_Tests.cs
index bf120d2e33..8fd3d68b18 100644
--- a/framework/test/Volo.Abp.Uow.Tests/Volo/Abp/Uow/UnitOfWork_Events_Tests.cs
+++ b/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;
diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs
index 6677f2d4a2..edb1f3f599 100644
--- a/modules/audit-logging/src/Volo.Abp.AuditLogging.EntityFrameworkCore/Volo/Abp/AuditLogging/EntityFrameworkCore/EfCoreAuditLogRepository.cs
+++ b/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 GetListQuery(
+ protected virtual async Task> 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> 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 WithDetails()
{
return GetQueryable().IncludeDetails();
}
+ public override async Task> WithDetailsAsync()
+ {
+ return (await GetQueryableAsync()).IncludeDetails();
+ }
+
public virtual async Task GetEntityChange(Guid entityChangeId)
{
- var entityChange = await DbContext.Set()
+ var entityChange = await (await GetDbContextAsync()).Set()
.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 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> GetEntityChangesWithUsernameAsync(string entityId, string entityTypeFullName)
{
- var query = DbContext.Set()
+ var dbContext = await GetDbContextAsync();
+
+ var query = dbContext.Set()
.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 GetEntityChangeListQuery(
+ protected virtual async Task> 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().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()
+ .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));
}
}
}
diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs b/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs
index 14e4dd39c7..95981d6355 100644
--- a/modules/audit-logging/src/Volo.Abp.AuditLogging.MongoDB/Volo/Abp/AuditLogging/MongoDB/MongoAuditLogRepository.cs
+++ b/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 GetListQuery(
+ protected virtual async Task> 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> 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 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>()
.PageBy>(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>().LongCountAsync(GetCancellationToken(cancellationToken));
@@ -197,7 +196,7 @@ namespace Volo.Abp.AuditLogging.MongoDB
public virtual async Task 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> 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>()
.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 GetEntityChangeListQuery(
+ protected virtual async Task> 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)
diff --git a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo/Abp/BackgroundJobs/EntityFrameworkCore/EfCoreBackgroundJobRepository.cs b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo/Abp/BackgroundJobs/EntityFrameworkCore/EfCoreBackgroundJobRepository.cs
index 29d2bb0170..1971faf380 100644
--- a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.EntityFrameworkCore/Volo/Abp/BackgroundJobs/EntityFrameworkCore/EfCoreBackgroundJobRepository.cs
+++ b/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 dbContextProvider,
- IClock clock)
+ IClock clock)
: base(dbContextProvider)
{
Clock = clock;
@@ -23,14 +23,13 @@ namespace Volo.Abp.BackgroundJobs.EntityFrameworkCore
public virtual async Task> GetWaitingListAsync(int maxResultCount)
{
- return await GetWaitingListQuery(maxResultCount)
- .ToListAsync();
+ return await (await GetWaitingListQueryAsync(maxResultCount)).ToListAsync();
}
- protected virtual IQueryable GetWaitingListQuery(int maxResultCount)
+ protected virtual async Task> 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)
diff --git a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.MongoDB/Volo/Abp/BackgroundJobs/MongoDB/MongoBackgroundJobRepository.cs b/modules/background-jobs/src/Volo.Abp.BackgroundJobs.MongoDB/Volo/Abp/BackgroundJobs/MongoDB/MongoBackgroundJobRepository.cs
index 4399e15a98..258c9310e2 100644
--- a/modules/background-jobs/src/Volo.Abp.BackgroundJobs.MongoDB/Volo/Abp/BackgroundJobs/MongoDB/MongoBackgroundJobRepository.cs
+++ b/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