diff --git a/src/CSharp/EasyMicroservices.Cores.AspCoreApi/MultilingualReadableQueryServiceController.cs b/src/CSharp/EasyMicroservices.Cores.AspCoreApi/MultilingualReadableQueryServiceController.cs index 75816d1..38c3540 100644 --- a/src/CSharp/EasyMicroservices.Cores.AspCoreApi/MultilingualReadableQueryServiceController.cs +++ b/src/CSharp/EasyMicroservices.Cores.AspCoreApi/MultilingualReadableQueryServiceController.cs @@ -265,4 +265,51 @@ protected virtual Func, IQueryable> OnGetAllQuery() { return null; } +} + + +/// +/// +/// +/// +/// +/// +/// +public class MultilingualReadableQueryServiceController + : MultilingualReadableQueryServiceController + where TResponseContract : class + where TLanguageResponseContract : class + where TEntity : class +{ + + /// + /// + /// + /// + public MultilingualReadableQueryServiceController(IContractReadableLogic contractReadable) + : base(contractReadable) + { + + } + + /// + /// + /// + /// + /// + public MultilingualReadableQueryServiceController(IBaseUnitOfWork unitOfWork, IContractReadableLogic contractReadable) + : base(unitOfWork, contractReadable) + { + + } + /// + /// + /// + /// + /// + public MultilingualReadableQueryServiceController(IBaseUnitOfWork unitOfWork) + : base(unitOfWork) + { + ContractLogic = unitOfWork.GetReadableContractLogic(); + } } \ No newline at end of file diff --git a/src/CSharp/EasyMicroservices.Cores.AspCoreApi/ReadableQueryServiceController.cs b/src/CSharp/EasyMicroservices.Cores.AspCoreApi/ReadableQueryServiceController.cs index 67278e1..03c2bfd 100644 --- a/src/CSharp/EasyMicroservices.Cores.AspCoreApi/ReadableQueryServiceController.cs +++ b/src/CSharp/EasyMicroservices.Cores.AspCoreApi/ReadableQueryServiceController.cs @@ -2,7 +2,6 @@ using EasyMicroservices.Cores.Contracts.Requests; using EasyMicroservices.Cores.Database.Interfaces; using EasyMicroservices.Cores.Interfaces; -using EasyMicroservices.Database.Interfaces; using EasyMicroservices.ServiceContracts; using Microsoft.AspNetCore.Mvc; using System; @@ -154,4 +153,49 @@ protected virtual Func, IQueryable> OnGetAllQuery() return null; } } + + /// + /// + /// + /// + /// + /// + public class ReadableQueryServiceController + : ReadableQueryServiceController + where TResponseContract : class + where TEntity : class + { + + /// + /// + /// + /// + public ReadableQueryServiceController(IContractReadableLogic contractReadable) + : base(contractReadable) + { + + } + + /// + /// + /// + /// + /// + public ReadableQueryServiceController(IBaseUnitOfWork unitOfWork, IContractReadableLogic contractReadable) + : base(unitOfWork, contractReadable) + { + + } + + /// + /// + /// + /// + /// + public ReadableQueryServiceController(IBaseUnitOfWork unitOfWork) + : base(unitOfWork) + { + + } + } } \ No newline at end of file diff --git a/src/CSharp/EasyMicroservices.Cores.Database/Database/Helpers/DatabaseExtensions.cs b/src/CSharp/EasyMicroservices.Cores.Database/Database/Helpers/DatabaseExtensions.cs index d74dad8..a353bf8 100644 --- a/src/CSharp/EasyMicroservices.Cores.Database/Database/Helpers/DatabaseExtensions.cs +++ b/src/CSharp/EasyMicroservices.Cores.Database/Database/Helpers/DatabaseExtensions.cs @@ -1,6 +1,7 @@ using EasyMicroservices.Cores.Database.Interfaces; using EasyMicroservices.Database.Interfaces; using System; +using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -22,4 +23,12 @@ public static void SetIdToRecordId(IContext context, TEn throw new Exception($"I cannot find any primary key in your {typeof(TEntity).Name}!"); idProperty.SetValue(recordEntity, ids.First()); } + + public static void SetIdToRecordId(IContext context, Dictionary records) + { + foreach (var item in records) + { + SetIdToRecordId(context, item.Key, item.Value); + } + } } diff --git a/src/CSharp/EasyMicroservices.Cores.Database/Database/Interfaces/IDatabaseWidget.cs b/src/CSharp/EasyMicroservices.Cores.Database/Database/Interfaces/IDatabaseWidget.cs index 3cccec7..f656807 100644 --- a/src/CSharp/EasyMicroservices.Cores.Database/Database/Interfaces/IDatabaseWidget.cs +++ b/src/CSharp/EasyMicroservices.Cores.Database/Database/Interfaces/IDatabaseWidget.cs @@ -1,4 +1,5 @@ using EasyMicroservices.Cores.Interfaces; +using System.Collections.Generic; using System.Threading.Tasks; namespace EasyMicroservices.Cores.Database.Interfaces; @@ -17,8 +18,16 @@ public interface IDatabaseWidget : IWidget /// /// /// - /// /// + /// + /// + Task AddProcess(IDatabaseWidgetManager databaseWidgetManager, IBaseUnitOfWork baseUnitOfWork, TEntity entity, T contract); + /// + /// + /// + /// + /// + /// /// - Task Process(IDatabaseWidgetManager databaseWidgetManager, IBaseUnitOfWork baseUnitOfWork, T contract, TEntity entity); + Task AddBulkProcess(IDatabaseWidgetManager databaseWidgetManager, IBaseUnitOfWork baseUnitOfWork, Dictionary items); } diff --git a/src/CSharp/EasyMicroservices.Cores.Database/Database/Interfaces/IDatabaseWidgetManager.cs b/src/CSharp/EasyMicroservices.Cores.Database/Database/Interfaces/IDatabaseWidgetManager.cs index ed7d7db..0804020 100644 --- a/src/CSharp/EasyMicroservices.Cores.Database/Database/Interfaces/IDatabaseWidgetManager.cs +++ b/src/CSharp/EasyMicroservices.Cores.Database/Database/Interfaces/IDatabaseWidgetManager.cs @@ -1,4 +1,5 @@ using EasyMicroservices.Cores.Interfaces; +using System.Collections.Generic; using System.Threading.Tasks; namespace EasyMicroservices.Cores.Database.Interfaces; @@ -13,9 +14,19 @@ public interface IDatabaseWidgetManager : IWidgetManager /// /// /// - /// /// + /// + /// + Task Add(IBaseUnitOfWork baseUnitOfWork, TEntity entity, T contract) + where TEntity : class; + /// + /// + /// + /// + /// + /// + /// /// - Task Add(IBaseUnitOfWork baseUnitOfWork, T contract, TEntity entity) + Task AddBulk(IBaseUnitOfWork baseUnitOfWork, Dictionary items) where TEntity : class; } diff --git a/src/CSharp/EasyMicroservices.Cores.Database/Database/Logics/DatabaseLogicInfrastructure.cs b/src/CSharp/EasyMicroservices.Cores.Database/Database/Logics/DatabaseLogicInfrastructure.cs index da6aac7..ed7ae16 100644 --- a/src/CSharp/EasyMicroservices.Cores.Database/Database/Logics/DatabaseLogicInfrastructure.cs +++ b/src/CSharp/EasyMicroservices.Cores.Database/Database/Logics/DatabaseLogicInfrastructure.cs @@ -467,7 +467,7 @@ protected async Task> Filter( var entityResult = await Filter(filterRequest, easyReadableQueryable, query, cancellationToken); if (!entityResult) return entityResult.ToAnotherListContract(); - var result = (ListMessageContract)await MapToListAsync(entityResult.Result); + var result = (ListMessageContract)await MapToListAsync(entityResult.Result); result.TotalCount = entityResult.TotalCount; return result; } @@ -509,7 +509,7 @@ protected async Task> GetAll( var entityResult = await GetAll(easyReadableQueryable, query, cancellationToken); if (!entityResult) return entityResult.ToAnotherListContract(); - var result = await MapToListAsync(entityResult.Result); + var result = await MapToListAsync(entityResult.Result); return result; } @@ -533,7 +533,7 @@ public async Task> GetAllByUniqueIdentity(); - var result = await MapToListAsync(entityResult.Result); + var result = await MapToListAsync(entityResult.Result); return result; } @@ -703,7 +703,7 @@ public async Task> Update UpdateBulk(IEasyWritableQueryableAsync easyWritableQueryable, UpdateBulkRequestContract request, bool updateOnlyChangedValue, CancellationToken cancellationToken = default) where TEntity : class { - var entities = await MapToListAsync(request.Items); + var entities = await MapToListAsync(request.Items); var result = await InternalUpdateBulk(easyWritableQueryable, entities, updateOnlyChangedValue, false, true, false, cancellationToken); return result; } @@ -974,7 +974,7 @@ await InternalUpdate(easyWritableQueryable, result.Entity, false, true, true, tr } } var widgetManager = _baseUnitOfWork.GetDatabaseWidgetManager(); - await widgetManager.Add(_baseUnitOfWork, contract, result.Entity); + await widgetManager.Add(_baseUnitOfWork, result.Entity, contract); await ActivityChangeLogLogic.AddAsync(result.Entity, _baseUnitOfWork); return result.Entity; } @@ -983,14 +983,15 @@ await InternalUpdate(easyWritableQueryable, result.Entity, false, true, true, tr /// /// /// + /// /// - /// + /// /// /// - public async Task> AddBulk(IEasyWritableQueryableAsync easyWritableQueryable, IEnumerable entities, CancellationToken cancellationToken = default) + internal async Task> AddBulk(IEasyWritableQueryableAsync easyWritableQueryable, Dictionary items, CancellationToken cancellationToken = default) where TEntity : class { - var result = await easyWritableQueryable.AddBulkAsync(entities, cancellationToken); + var result = await easyWritableQueryable.AddBulkAsync(items.Values, cancellationToken); var allItems = easyWritableQueryable.Context.GetTrackerEntities().ToArray(); await CheckUniqueIdentityAccess(allItems).AsCheckedResult(); @@ -1025,7 +1026,9 @@ await InternalUpdateBulk(easyWritableQueryable, result.Select(x => x.Entity).ToL await easyWritableQueryable.SaveChangesAsync(); } var response = result.Select(x => x.Entity).ToList(); - await ActivityChangeLogLogic.AddBulkAsync(response, _baseUnitOfWork); + var widgetManager = _baseUnitOfWork.GetDatabaseWidgetManager(); + await widgetManager.AddBulk(_baseUnitOfWork, items); + await ActivityChangeLogLogic.AddBuldAsync(response, _baseUnitOfWork); return response; } @@ -1042,7 +1045,7 @@ public async Task> Add(IEasyWritabl where TEntity : class { var entity = await MapAsync(contract); - var result = await Add(easyWritableQueryable, entity, contract, cancellationToken); + var result = await Add(easyWritableQueryable, entity, contract, cancellationToken); return result; } @@ -1058,8 +1061,8 @@ public async Task> Add(IEasyWritabl public async Task> AddBulk(IEasyWritableQueryableAsync easyWritableQueryable, CreateBulkRequestContract request, CancellationToken cancellationToken = default) where TEntity : class { - var entities = await MapToListAsync(request.Items); - var result = await AddBulk(easyWritableQueryable, entities, cancellationToken); + var items = await MapToDictionaryAsync(request.Items); + var result = await AddBulk(easyWritableQueryable, items, cancellationToken); return result; } @@ -1074,7 +1077,7 @@ public async Task> AddBulk(IEas /// /// /// - protected async Task> MapToListAsync(IEnumerable items) + protected async Task> MapToListAsync(IEnumerable items) { if (typeof(TFrom) == typeof(TTo)) return items.Cast().ToList(); @@ -1083,6 +1086,22 @@ protected async Task> MapToListAsync(IEnumerable it return result; } + /// + /// + /// + /// + /// + /// + /// + protected async Task> MapToDictionaryAsync(IEnumerable items) + { + if (typeof(TFrom) == typeof(TTo)) + return items.Cast().ToDictionary(x => (TFrom)x, x => (TTo)x); + var result = await MapperProvider.MapToDictionaryAsync(items); + ValidateMappedResult(ref result); + return result; + } + /// /// /// diff --git a/src/CSharp/EasyMicroservices.Cores.Database/Database/Managers/DatabaseWidgetManager.cs b/src/CSharp/EasyMicroservices.Cores.Database/Database/Managers/DatabaseWidgetManager.cs index 539d5bd..ec7e9ae 100644 --- a/src/CSharp/EasyMicroservices.Cores.Database/Database/Managers/DatabaseWidgetManager.cs +++ b/src/CSharp/EasyMicroservices.Cores.Database/Database/Managers/DatabaseWidgetManager.cs @@ -1,6 +1,8 @@ using EasyMicroservices.Cores.Database.Interfaces; using EasyMicroservices.Cores.Interfaces; using EasyMicroservices.Cores.Widgets; +using System.Collections.Generic; +using System.Diagnostics.Contracts; using System.Threading.Tasks; namespace EasyMicroservices.Cores.Database.Managers; @@ -16,10 +18,10 @@ public class DatabaseWidgetManager : WidgetManager, IDatabaseWidgetManager /// /// /// - /// /// + /// /// - public async Task Add(IBaseUnitOfWork baseUnitOfWork, T contract, TEntity entity) + public async Task Add(IBaseUnitOfWork baseUnitOfWork, TEntity entity, T contract) where TEntity : class { var widgets = GetWidgetsByType(typeof(T)); @@ -27,7 +29,27 @@ public async Task Add(IBaseUnitOfWork baseUnitOfWork, T contract, TE { if (widget is IDatabaseWidget databaseWidget && databaseWidget.CanProcess(baseUnitOfWork)) { - await databaseWidget.Process(this, baseUnitOfWork, contract, entity); + await databaseWidget.AddProcess(this, baseUnitOfWork, entity, contract); + } + } + } + + /// + /// + /// + /// + /// + /// + /// + /// + public async Task AddBulk(IBaseUnitOfWork baseUnitOfWork, Dictionary items) where TEntity : class + { + var widgets = GetWidgetsByType(typeof(T)); + foreach (var widget in widgets) + { + if (widget is IDatabaseWidget databaseWidget && databaseWidget.CanProcess(baseUnitOfWork)) + { + await databaseWidget.AddBulkProcess(this, baseUnitOfWork, items); } } } diff --git a/src/CSharp/EasyMicroservices.Cores.Database/Database/Widgets/SimpleReportingEntityWidget.cs b/src/CSharp/EasyMicroservices.Cores.Database/Database/Widgets/SimpleReportingEntityWidget.cs index c6970ce..1070525 100644 --- a/src/CSharp/EasyMicroservices.Cores.Database/Database/Widgets/SimpleReportingEntityWidget.cs +++ b/src/CSharp/EasyMicroservices.Cores.Database/Database/Widgets/SimpleReportingEntityWidget.cs @@ -3,6 +3,8 @@ using EasyMicroservices.Cores.Interfaces; using EasyMicroservices.ServiceContracts; using System; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; namespace EasyMicroservices.Cores.Widgets; @@ -60,11 +62,11 @@ public Task Initialize(params TObjectContract[] parameters) /// /// /// - /// /// + /// /// /// - public async Task Process(IDatabaseWidgetManager databaseWidgetManager, IBaseUnitOfWork baseUnitOfWork, TObjectContract contract, TEntity entity) + public async Task AddProcess(IDatabaseWidgetManager databaseWidgetManager, IBaseUnitOfWork baseUnitOfWork, TEntity entity, TObjectContract contract) { var reportEntity = await baseUnitOfWork .GetMapper() @@ -78,4 +80,26 @@ await logic .Add(reportEntity) .AsCheckedResult(); } + + /// + /// + /// + /// + /// + /// + /// + public async Task AddBulkProcess(IDatabaseWidgetManager databaseWidgetManager, IBaseUnitOfWork baseUnitOfWork, Dictionary items) + { + var reportEntities = await baseUnitOfWork + .GetMapper() + .MapToDictionaryAsync(items.Keys); + var logic = baseUnitOfWork.GetLogic(new Models.LogicOptions() + { + DoStopReporting = true + }); + DatabaseExtensions.SetIdToRecordId(logic.GetReadableContext(), reportEntities); + await logic + .AddBulk(reportEntities.Values.ToList()) + .AsCheckedResult(); + } }