diff --git a/common.DotSettings b/common.DotSettings index 7edbd05e75..5c1cda48fd 100644 --- a/common.DotSettings +++ b/common.DotSettings @@ -29,6 +29,7 @@ Never Never Never + True True True False diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/BasicRepositoryBase.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/BasicRepositoryBase.cs index ae1b03475c..1235dc3714 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/BasicRepositoryBase.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/BasicRepositoryBase.cs @@ -2,15 +2,18 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using Volo.Abp.Data; using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Entities; +using Volo.Abp.Linq; +using Volo.Abp.MultiTenancy; using Volo.Abp.Threading; using Volo.Abp.Uow; namespace Volo.Abp.Domain.Repositories { - public abstract class BasicRepositoryBase : - IBasicRepository, + public abstract class BasicRepositoryBase : + IBasicRepository, IServiceProviderAccessor, IUnitOfWorkEnabled, ITransientDependency @@ -18,6 +21,14 @@ namespace Volo.Abp.Domain.Repositories { public IServiceProvider ServiceProvider { get; set; } + public IDataFilter DataFilter { get; set; } + + public ICurrentTenant CurrentTenant { get; set; } + + public IAsyncQueryableExecuter AsyncExecuter { get; set; } + + public IUnitOfWorkManager UnitOfWorkManager { get; set; } + public ICancellationTokenProvider CancellationTokenProvider { get; set; } protected BasicRepositoryBase() @@ -27,6 +38,29 @@ namespace Volo.Abp.Domain.Repositories public abstract Task InsertAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default); + public virtual async Task InsertManyAsync(IEnumerable entities, bool autoSave = false, CancellationToken cancellationToken = default) + { + foreach (var entity in entities) + { + await InsertAsync(entity, cancellationToken: cancellationToken); + } + + if (autoSave) + { + await SaveChangesAsync(cancellationToken); + } + } + + protected virtual Task SaveChangesAsync(CancellationToken cancellationToken) + { + if (UnitOfWorkManager?.Current != null) + { + return UnitOfWorkManager?.Current.SaveChangesAsync(cancellationToken); + } + + return Task.CompletedTask; + } + public abstract Task UpdateAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default); public abstract Task DeleteAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default); @@ -59,7 +93,7 @@ namespace Volo.Abp.Domain.Repositories } public abstract Task FindAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default); - + public virtual async Task DeleteAsync(TKey id, bool autoSave = false, CancellationToken cancellationToken = default) { var entity = await FindAsync(id, cancellationToken: cancellationToken); diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IBasicRepository.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IBasicRepository.cs index 6b62691ed8..0637225229 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IBasicRepository.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/Repositories/IBasicRepository.cs @@ -1,4 +1,5 @@ -using System.Threading; +using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using JetBrains.Annotations; using Volo.Abp.Domain.Entities; @@ -20,8 +21,10 @@ namespace Volo.Abp.Domain.Repositories [NotNull] Task InsertAsync([NotNull] TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default); + Task InsertManyAsync([NotNull] IEnumerable entities, bool autoSave = false, CancellationToken cancellationToken = default); + /// - /// Updates an existing entity. + /// Updates an existing entity. /// /// /// Set true to automatically save changes to database. 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 fd66b293c9..6c4d7a31f4 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 @@ -16,14 +16,6 @@ namespace Volo.Abp.Domain.Repositories public abstract class RepositoryBase : BasicRepositoryBase, IRepository, IUnitOfWorkManagerAccessor where TEntity : class, IEntity { - public IDataFilter DataFilter { get; set; } - - public ICurrentTenant CurrentTenant { get; set; } - - public IAsyncQueryableExecuter AsyncExecuter { get; set; } - - public IUnitOfWorkManager UnitOfWorkManager { get; set; } - public virtual Type ElementType => GetQueryable().ElementType; public virtual Expression Expression => GetQueryable().Expression; 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 0d44fd1249..c8e4b6e7e4 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 @@ -32,6 +32,8 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore public virtual IGuidGenerator GuidGenerator { get; set; } + public IEfCoreBulkOperationProvider BulkOperationProvider { get; set; } + public EfCoreRepository(IDbContextProvider dbContextProvider) { _dbContextProvider = dbContextProvider; @@ -110,11 +112,32 @@ namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore .ToListAsync(GetCancellationToken(cancellationToken)); } + public override async Task InsertManyAsync(IEnumerable entities, bool autoSave = false, CancellationToken cancellationToken = default) + { + if (BulkOperationProvider != null) + { + await BulkOperationProvider.InsertManyAsync( + this, + entities, + autoSave, + cancellationToken + ); + return; + } + + await base.InsertManyAsync(entities, autoSave, cancellationToken); + } + protected override IQueryable GetQueryable() { return DbSet.AsQueryable(); } + protected override Task SaveChangesAsync(CancellationToken cancellationToken) + { + return DbContext.SaveChangesAsync(cancellationToken); + } + public async override Task FindAsync( Expression> predicate, bool includeDetails = true, diff --git a/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/IEfCoreBulkOperationProvider.cs b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/IEfCoreBulkOperationProvider.cs new file mode 100644 index 0000000000..6ff6e2bdc0 --- /dev/null +++ b/framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/Domain/Repositories/EntityFrameworkCore/IEfCoreBulkOperationProvider.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.Domain.Entities; +using Volo.Abp.EntityFrameworkCore; + +namespace Volo.Abp.Domain.Repositories.EntityFrameworkCore +{ + public interface IEfCoreBulkOperationProvider + { + Task InsertManyAsync( + IEfCoreRepository repository, + IEnumerable entities, + bool autoSave, + CancellationToken cancellationToken + ) + where TDbContext : IEfCoreDbContext + where TEntity : class, IEntity; + } +}