From 1f975818743601bae8f8a981d09070c09b5b6a07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sedat=20=C3=96zt=C3=BCrk?= Date: Wed, 4 Feb 2026 21:51:05 +0300 Subject: [PATCH] =?UTF-8?q?ListForm=20AppService=20performans=20g=C3=BC?= =?UTF-8?q?=C3=A7lendirmesi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ListFormCustomizationAppService.cs | 82 +++++++------- .../ListForms/ListFormImportAppService.cs | 59 ++++++---- .../ListForms/ListFormWizardAppService.cs | 107 ++++++++++-------- 3 files changed, 138 insertions(+), 110 deletions(-) diff --git a/api/src/Erp.Platform.Application/ListForms/ListFormCustomizationAppService.cs b/api/src/Erp.Platform.Application/ListForms/ListFormCustomizationAppService.cs index c8d368c9..53ee1e05 100644 --- a/api/src/Erp.Platform.Application/ListForms/ListFormCustomizationAppService.cs +++ b/api/src/Erp.Platform.Application/ListForms/ListFormCustomizationAppService.cs @@ -11,6 +11,7 @@ using Microsoft.EntityFrameworkCore; using Volo.Abp; using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Repositories; +using Volo.Abp.Uow; using static Erp.Platform.PlatformConsts; namespace Erp.Platform.ListForms; @@ -46,42 +47,35 @@ public class ListFormCustomizationAppService : PlatformAppService throw new BadHttpRequestException("Type UI veya Grid olmalıdır"); } - var query = await repository.GetQueryableAsync(); + var queryable = await repository.GetQueryableAsync(); - var itemsUser = await query - .Where(a => + // Tek query ile tüm ilgili kayıtları çek (3 query yerine 1) + var allItems = await AsyncExecuter.ToListAsync( + queryable.Where(a => a.ListFormCode == listFormCode && - a.UserId == CurrentUser.UserName && - a.RoleId == null && - a.CustomizationType == type) + a.CustomizationType == type && + ( + // User customizations + (a.UserId == CurrentUser.UserName && a.RoleId == null) || + // Role customizations + (a.UserId == null && CurrentUser.Roles.Contains(a.RoleId)) || + // Global customizations + (a.UserId == null && a.RoleId == null) + ) + ) .WhereIf(!filterName.IsNullOrWhiteSpace(), a => a.FilterName == filterName) - .ToListAsync(); - var itemsRole = await query - .Where(a => - a.ListFormCode == listFormCode && - a.UserId == null && - CurrentUser.Roles.Contains(a.RoleId) && - a.CustomizationType == type) - .WhereIf(!filterName.IsNullOrWhiteSpace(), a => a.FilterName == filterName) - .ToListAsync(); - var itemsGlobal = await query - .Where(a => - a.ListFormCode == listFormCode && - a.UserId == null && - a.RoleId == null && - a.CustomizationType == type) - .WhereIf(!filterName.IsNullOrWhiteSpace(), a => a.FilterName == filterName) - .ToListAsync(); + ); - var items = new List(); - items.AddRange(itemsUser); - items.AddRange(itemsRole); - items.AddRange(itemsGlobal); + // Öncelik sırasına göre sırala: User > Role > Global + var items = allItems + .OrderByDescending(a => a.UserId != null ? 3 : (a.RoleId != null ? 2 : 1)) + .ToList(); return ObjectMapper.Map, List>(items); } //Bu hem update, hem create yapıyor + [UnitOfWork] public async Task CreateAsync(CreateUpdateListFormCustomizationForUserDto input) { await CheckAccessAsync(input.ListFormCode); @@ -94,12 +88,15 @@ public class ListFormCustomizationAppService : PlatformAppService throw new BadHttpRequestException("Filter data boş olamaz"); } - var item = await repository.FirstOrDefaultAsync(a => - a.ListFormCode == input.ListFormCode && - a.UserId == CurrentUser.UserName && - a.RoleId == null && - a.FilterName == input.FilterName && - a.CustomizationType == input.CustomizationType); + var queryable = await repository.GetQueryableAsync(); + var item = await AsyncExecuter.FirstOrDefaultAsync( + queryable.Where(a => + a.ListFormCode == input.ListFormCode && + a.UserId == CurrentUser.UserName && + a.RoleId == null && + a.FilterName == input.FilterName && + a.CustomizationType == input.CustomizationType) + ); if (item == null) { @@ -111,13 +108,13 @@ public class ListFormCustomizationAppService : PlatformAppService ListFormCode = input.ListFormCode, UserId = CurrentUser.UserName }; - await repository.InsertAsync(item); + await repository.InsertAsync(item, autoSave: true); } else { item.FilterName = input.FilterName; item.CustomizationData = input.CustomizationData; - await repository.UpdateAsync(item); + await repository.UpdateAsync(item, autoSave: true); } return ObjectMapper.Map(item); @@ -125,11 +122,14 @@ public class ListFormCustomizationAppService : PlatformAppService public async Task DeleteAsync(Guid id) { - var item = await repository.FirstOrDefaultAsync(a => - a.Id == id && - a.UserId == CurrentUser.UserName && - a.RoleId == null + var queryable = await repository.GetQueryableAsync(); + var item = await AsyncExecuter.FirstOrDefaultAsync( + queryable.Where(a => + a.Id == id && + a.UserId == CurrentUser.UserName && + a.RoleId == null) ); + if (item == null) { throw new EntityNotFoundException("Item not found"); @@ -142,8 +142,6 @@ public class ListFormCustomizationAppService : PlatformAppService await CheckAccessAsync(item.ListFormCode); - await repository.DeleteAsync(item); + await repository.DeleteAsync(item, autoSave: true); } - } - diff --git a/api/src/Erp.Platform.Application/ListForms/ListFormImportAppService.cs b/api/src/Erp.Platform.Application/ListForms/ListFormImportAppService.cs index ce2b3a40..2508506e 100644 --- a/api/src/Erp.Platform.Application/ListForms/ListFormImportAppService.cs +++ b/api/src/Erp.Platform.Application/ListForms/ListFormImportAppService.cs @@ -15,6 +15,7 @@ using Volo.Abp; using Volo.Abp.Content; using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Repositories; +using Volo.Abp.Uow; using static Erp.Platform.PlatformConsts; namespace Erp.Platform.ListForms.ImportManager; @@ -89,7 +90,8 @@ public class ListFormImportAppService : PlatformAppService, IImportAppService public async Task GetAsync(Guid id) { - var session = await _importSessionRepository.FirstOrDefaultAsync(a => a.Id == id) + var queryable = await _importSessionRepository.GetQueryableAsync(); + var session = await AsyncExecuter.FirstOrDefaultAsync(queryable.Where(a => a.Id == id)) ?? throw new EntityNotFoundException(typeof(ListFormImport), id); if (!await _authManager.CanAccess(session.ListFormCode, AuthorizationTypeEnum.Import)) @@ -103,10 +105,14 @@ public class ListFormImportAppService : PlatformAppService, IImportAppService if (!await _authManager.CanAccess(listFormCode, AuthorizationTypeEnum.Import)) throw new Volo.Abp.UserFriendlyException(L[AppErrorCodes.NoAuth]); - var sessions = await _importSessionRepository.GetListAsync(x => x.ListFormCode == listFormCode); + var queryable = await _importSessionRepository.GetQueryableAsync(); + var sessions = await AsyncExecuter.ToListAsync( + queryable + .Where(x => x.ListFormCode == listFormCode) + .OrderByDescending(x => x.CreationTime) + ); - var ordered = sessions.OrderByDescending(x => x.CreationTime).ToList(); - return ObjectMapper.Map, List>(ordered); + return ObjectMapper.Map, List>(sessions); } @@ -116,7 +122,8 @@ public class ListFormImportAppService : PlatformAppService, IImportAppService if (!await _authManager.CanAccess(input.ListFormCode, AuthorizationTypeEnum.Import)) throw new Volo.Abp.UserFriendlyException(L[AppErrorCodes.NoAuth]); - var session = await _importSessionRepository.FirstOrDefaultAsync(a => a.Id == id) + var queryable = await _importSessionRepository.GetQueryableAsync(); + var session = await AsyncExecuter.FirstOrDefaultAsync(queryable.Where(a => a.Id == id)) ?? throw new EntityNotFoundException(typeof(ListFormImport), id); if (!string.IsNullOrEmpty(input.Status)) session.Status = input.Status; @@ -126,9 +133,11 @@ public class ListFormImportAppService : PlatformAppService, IImportAppService return ObjectMapper.Map(session); } + [UnitOfWork] public async Task ExecuteAsync([FromBody] ExecuteImportRequest request) { - var session = await _importSessionRepository.FirstOrDefaultAsync(a => a.Id == request.SessionId) + var queryable = await _importSessionRepository.GetQueryableAsync(); + var session = await AsyncExecuter.FirstOrDefaultAsync(queryable.Where(a => a.Id == request.SessionId)) ?? throw new UserFriendlyException("Import session not found."); // Izin logic process @@ -159,6 +168,10 @@ public class ListFormImportAppService : PlatformAppService, IImportAppService execute.Progress = 20; await _importSessionExecuteRepository.UpdateAsync(execute, autoSave: true); + // Batch processing için - daha az update + const int updateInterval = 50; // Her 50 satırda bir update + var lastUpdateIndex = 0; + // Process each row individually for (int i = 0; i < request.SelectedRowsData.Count; i++) { @@ -177,17 +190,20 @@ public class ListFormImportAppService : PlatformAppService, IImportAppService // If database insert fails, count as error errorCount++; // Log the error if needed - Logger.LogWarning("Error inserting row {0} during import for session {1}: {2}", i, session.Id, ex.Message); + Logger.LogWarning("Error inserting row {RowIndex} during import for session {SessionId}: {ErrorMessage}", i, session.Id, ex.Message); } - // Update progress - var progressPercentage = 20 + (int)((double)(i + 1) / processedCount * 70); // Progress from 20% to 90% - execute.Progress = progressPercentage; - - // Update progress every 10 rows or on last row to avoid too many database updates - if ((i + 1) % 10 == 0 || i == processedCount - 1) + // Update progress - optimizasyon: daha az update + if ((i + 1 - lastUpdateIndex >= updateInterval) || i == processedCount - 1) { - await _importSessionExecuteRepository.UpdateAsync(execute, autoSave: true); + var progressPercentage = 20 + (int)((double)(i + 1) / processedCount * 70); // Progress from 20% to 90% + execute.Progress = progressPercentage; + execute.ExecRows = i + 1; + execute.ValidRows = validCount; + execute.ErrorRows = errorCount; + + await _importSessionExecuteRepository.UpdateAsync(execute, autoSave: false); + lastUpdateIndex = i + 1; } } } @@ -216,22 +232,27 @@ public class ListFormImportAppService : PlatformAppService, IImportAppService public async Task> GetListExecutesAsync(Guid sessionId) { - var sessions = await _importSessionExecuteRepository.GetListAsync(x => x.ImportId == sessionId); + var queryable = await _importSessionExecuteRepository.GetQueryableAsync(); + var sessions = await AsyncExecuter.ToListAsync( + queryable + .Where(x => x.ImportId == sessionId) + .OrderByDescending(x => x.CreationTime) + ); - var ordered = sessions.OrderByDescending(x => x.CreationTime).ToList(); - return ObjectMapper.Map, List>(ordered); + return ObjectMapper.Map, List>(sessions); } public async Task DeleteAsync(Guid id) { - var session = await _importSessionRepository.FirstOrDefaultAsync(a => a.Id == id) + var queryable = await _importSessionRepository.GetQueryableAsync(); + var session = await AsyncExecuter.FirstOrDefaultAsync(queryable.Where(a => a.Id == id)) ?? throw new EntityNotFoundException(typeof(ListFormImport), id); // Izin logic process if (!await _authManager.CanAccess(session.ListFormCode, AuthorizationTypeEnum.Import)) throw new Volo.Abp.UserFriendlyException(L[AppErrorCodes.NoAuth]); - await _importSessionRepository.DeleteAsync(id); + await _importSessionRepository.DeleteAsync(id, autoSave: true); } } diff --git a/api/src/Erp.Platform.Application/ListForms/ListFormWizardAppService.cs b/api/src/Erp.Platform.Application/ListForms/ListFormWizardAppService.cs index d8c62b3b..62b5c0be 100644 --- a/api/src/Erp.Platform.Application/ListForms/ListFormWizardAppService.cs +++ b/api/src/Erp.Platform.Application/ListForms/ListFormWizardAppService.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Text.Json; using System.Threading.Tasks; using Erp.Languages.Entities; @@ -10,7 +11,7 @@ using Volo.Abp.Domain.Repositories; using Volo.Abp.Identity; using Volo.Abp.MultiTenancy; using Volo.Abp.PermissionManagement; -using static Erp.Settings.SettingsConsts; +using Volo.Abp.Uow; namespace Erp.Platform.ListForms; @@ -41,6 +42,7 @@ public class ListFormWizardAppService( private readonly ILookupNormalizer lookupNormalizer = LookupNormalizer; private readonly string cultureNameDefault = PlatformConsts.DefaultLanguage; + [UnitOfWork] public async Task Create(WizardCreateInputDto input) { var listFormCode = input.ListFormCode; @@ -48,42 +50,45 @@ public class ListFormWizardAppService( var titleLangKey = PlatformConsts.Wizard.WizardKeyTitle(listFormCode); var code = PlatformConsts.Wizard.WizardKey(listFormCode); - //Dil - // Dil Key - // App.Platform.Form-001 => Text EN: ..., Text TR: ... - // App.Platform.Form-001.Title => Text EN: ..., Text TR: ... + //Dil - Language Keys await CreateLangKey(nameLangKey, input.LanguageTextMenuEn, input.LanguageTextMenuTr); await CreateLangKey(titleLangKey, input.LanguageTextTitleEn, input.LanguageTextTitleTr); await CreateLangKey(PlatformConsts.Wizard.WizardKeyDesc(listFormCode), input.LanguageTextDescEn, input.LanguageTextDescTr); - //Permission - // Group Name => Platform - // App.Platform.Form-001 => LanguageKey: App.Platform.Form-001.Menu, Parent Name: Ø - // App.Platform.Form-001.Create => LanguageKey: App.Create, Parent Name: App.Platform.Form-001 - // App.Platform.Form-001.Update => LanguageKey: App.Update, Parent Name: App.Platform.Form-001 - // App.Platform.Form-001.Delete => LanguageKey: App.Delete, Parent Name: App.Platform.Form-001 - // Dil - // Dil Key + //Permission Group var groupName = input.PermissionGroupName ?? PlatformConsts.AppName; if (!await repoPermGroup.AnyAsync(a => a.Name == groupName)) { - await repoPermGroup.InsertAsync(new PermissionGroupDefinitionRecord(GuidGenerator.Create(), groupName, groupName)); + await repoPermGroup.InsertAsync(new PermissionGroupDefinitionRecord(GuidGenerator.Create(), groupName, groupName), autoSave: false); await CreateLangKey(groupName, groupName, groupName); } - var permRead = await repoPerm.FirstOrDefaultAsync(a => a.GroupName == groupName && a.Name == code) ?? - await repoPerm.InsertAsync(new PermissionDefinitionRecord(Guid.NewGuid(), groupName, code, null, nameLangKey, true, MultiTenancySides.Both)); - var permCreate = await repoPerm.FirstOrDefaultAsync(a => a.GroupName == groupName && a.Name == PlatformConsts.Wizard.PermCreate(listFormCode)) ?? - await repoPerm.InsertAsync(new PermissionDefinitionRecord(Guid.NewGuid(), groupName, PlatformConsts.Wizard.PermCreate(listFormCode), permRead.Name, PlatformConsts.Wizard.LangKeyCreate, true, MultiTenancySides.Both)); - var permUpdate = await repoPerm.FirstOrDefaultAsync(a => a.GroupName == groupName && a.Name == PlatformConsts.Wizard.PermUpdate(listFormCode)) ?? - await repoPerm.InsertAsync(new PermissionDefinitionRecord(Guid.NewGuid(), groupName, PlatformConsts.Wizard.PermUpdate(listFormCode), permRead.Name, PlatformConsts.Wizard.LangKeyUpdate, true, MultiTenancySides.Both)); - var permDelete = await repoPerm.FirstOrDefaultAsync(a => a.GroupName == groupName && a.Name == PlatformConsts.Wizard.PermDelete(listFormCode)) ?? - await repoPerm.InsertAsync(new PermissionDefinitionRecord(Guid.NewGuid(), groupName, PlatformConsts.Wizard.PermDelete(listFormCode), permRead.Name, PlatformConsts.Wizard.LangKeyDelete, true, MultiTenancySides.Both)); - var permExport = await repoPerm.FirstOrDefaultAsync(a => a.GroupName == groupName && a.Name == PlatformConsts.Wizard.PermExport(listFormCode)) ?? - await repoPerm.InsertAsync(new PermissionDefinitionRecord(Guid.NewGuid(), groupName, PlatformConsts.Wizard.PermExport(listFormCode), permRead.Name, PlatformConsts.Wizard.LangKeyExport, true, MultiTenancySides.Both)); + // Permission'ları tek seferde kontrol et ve oluştur + var queryable = await repoPerm.GetQueryableAsync(); + var existingPerms = await AsyncExecuter.ToListAsync( + queryable.Where(a => a.GroupName == groupName) + ); + + var permRead = existingPerms.FirstOrDefault(a => a.Name == code) ?? + await repoPerm.InsertAsync(new PermissionDefinitionRecord(Guid.NewGuid(), groupName, code, null, nameLangKey, true, MultiTenancySides.Both), autoSave: false); + + var permCreate = existingPerms.FirstOrDefault(a => a.Name == PlatformConsts.Wizard.PermCreate(listFormCode)) ?? + await repoPerm.InsertAsync(new PermissionDefinitionRecord(Guid.NewGuid(), groupName, PlatformConsts.Wizard.PermCreate(listFormCode), permRead.Name, PlatformConsts.Wizard.LangKeyCreate, true, MultiTenancySides.Both), autoSave: false); + + var permUpdate = existingPerms.FirstOrDefault(a => a.Name == PlatformConsts.Wizard.PermUpdate(listFormCode)) ?? + await repoPerm.InsertAsync(new PermissionDefinitionRecord(Guid.NewGuid(), groupName, PlatformConsts.Wizard.PermUpdate(listFormCode), permRead.Name, PlatformConsts.Wizard.LangKeyUpdate, true, MultiTenancySides.Both), autoSave: false); + + var permDelete = existingPerms.FirstOrDefault(a => a.Name == PlatformConsts.Wizard.PermDelete(listFormCode)) ?? + await repoPerm.InsertAsync(new PermissionDefinitionRecord(Guid.NewGuid(), groupName, PlatformConsts.Wizard.PermDelete(listFormCode), permRead.Name, PlatformConsts.Wizard.LangKeyDelete, true, MultiTenancySides.Both), autoSave: false); + + var permExport = existingPerms.FirstOrDefault(a => a.Name == PlatformConsts.Wizard.PermExport(listFormCode)) ?? + await repoPerm.InsertAsync(new PermissionDefinitionRecord(Guid.NewGuid(), groupName, PlatformConsts.Wizard.PermExport(listFormCode), permRead.Name, PlatformConsts.Wizard.LangKeyExport, true, MultiTenancySides.Both), autoSave: false); + + // Permission Grants - Bulk Insert var adminUserName = PlatformConsts.AbpIdentity.User.AdminEmailDefaultValue; var adminUser = await userRepository.FindByNormalizedUserNameAsync(lookupNormalizer.NormalizeName(adminUserName)); var adminRole = await roleRepository.FindByNormalizedNameAsync(lookupNormalizer.NormalizeName(PlatformConsts.AbpIdentity.User.AdminRoleName)); + await permissionGrantRepository.InsertManyAsync( [ new PermissionGrant(Guid.NewGuid(), permRead.Name, "R", PlatformConsts.AbpIdentity.User.AdminRoleName), @@ -91,17 +96,11 @@ public class ListFormWizardAppService( new PermissionGrant(Guid.NewGuid(), permUpdate.Name, "R", PlatformConsts.AbpIdentity.User.AdminRoleName), new PermissionGrant(Guid.NewGuid(), permDelete.Name, "R", PlatformConsts.AbpIdentity.User.AdminRoleName), new PermissionGrant(Guid.NewGuid(), permExport.Name, "R", PlatformConsts.AbpIdentity.User.AdminRoleName), - ]); + ], autoSave: false); - //Menu - // App.Platform.Form-001 => LanguageKey: App.Platform.Form-001.Menu, Permission: App.Platform.Form-001, Parent Name: Platform - // Permission - // Group Name - // Dil - // Dil Key - // Dil - // Dil Key - var menuParent = await repoMenu.FirstOrDefaultAsync(a => a.Code == input.MenuParentCode); + //Menu Parent + var menuQueryable = await repoMenu.GetQueryableAsync(); + var menuParent = await AsyncExecuter.FirstOrDefaultAsync(menuQueryable.Where(a => a.Code == input.MenuParentCode)); if (menuParent == null) { await CreateLangKey(PlatformConsts.Wizard.WizardKeyParent(listFormCode), input.LanguageTextMenuParentEn, input.LanguageTextMenuParentTr); @@ -110,9 +109,11 @@ public class ListFormWizardAppService( Code = input.MenuParentCode, DisplayName = PlatformConsts.Wizard.WizardKeyParent(listFormCode), IsDisabled = false, - }); + }, autoSave: false); } - var menu = await repoMenu.FirstOrDefaultAsync(a => a.Code == code) ?? + + //Menu + var menu = await AsyncExecuter.FirstOrDefaultAsync(menuQueryable.Where(a => a.Code == code)) ?? await repoMenu.InsertAsync(new Menu { Code = code, @@ -125,10 +126,11 @@ public class ListFormWizardAppService( CssClass = null, Url = PlatformConsts.Wizard.MenuUrl(listFormCode), RequiredPermissionName = permRead.Name - }); + }, autoSave: false); //Data Source - var dataSource = repoDataSource.FirstOrDefaultAsync(a => a.Code == input.DataSourceCode); + var dataSourceQueryable = await repoDataSource.GetQueryableAsync(); + var dataSource = await AsyncExecuter.FirstOrDefaultAsync(dataSourceQueryable.Where(a => a.Code == input.DataSourceCode)); if (dataSource is null) { await repoDataSource.InsertAsync(new DataSource @@ -136,7 +138,7 @@ public class ListFormWizardAppService( Code = input.DataSourceCode, DataSourceType = input.DataSourceConnectionString.IndexOf("Server") >= 0 ? DataSourceTypeEnum.Mssql : DataSourceTypeEnum.Postgresql, ConnectionString = input.DataSourceConnectionString - }); + }, autoSave: false); } //ListForm @@ -148,7 +150,7 @@ public class ListFormWizardAppService( Title = titleLangKey, CultureName = PlatformConsts.DefaultLanguage, Description = PlatformConsts.Wizard.WizardKeyDesc(listFormCode), - SelectCommandType = input.SelectCommandType, //SelectCommandTypeEnum.Table, + SelectCommandType = input.SelectCommandType, SelectCommand = input.SelectCommand, KeyFieldName = input.KeyFieldName, KeyFieldDbSourceType = input.KeyFieldDbSourceType, @@ -159,21 +161,28 @@ public class ListFormWizardAppService( U = permUpdate.Name, D = permDelete.Name }), - }); + }, autoSave: true); } private async Task CreateLangKey(string key, string textEn, string textTr) { var res = PlatformConsts.AppName; - var langKey = await repoLangKey.FirstOrDefaultAsync(a => a.ResourceName == res && a.Key == key) - ?? await repoLangKey.InsertAsync(new LanguageKey { ResourceName = res, Key = key }); - var langTextEn = await repoLangText.FirstOrDefaultAsync(a => a.ResourceName == res && a.Key == langKey.Key && a.CultureName == cultureNameDefault) - ?? await repoLangText.InsertAsync(new LanguageText { ResourceName = res, Key = langKey.Key, CultureName = cultureNameDefault, Value = textEn }); - var langTextTitleTr = await repoLangText.FirstOrDefaultAsync(a => a.ResourceName == res && a.Key == langKey.Key && a.CultureName == LanguageCodes.Tr) - ?? await repoLangText.InsertAsync(new LanguageText { ResourceName = res, Key = langKey.Key, CultureName = LanguageCodes.En, Value = textTr }); + + var keyQueryable = await repoLangKey.GetQueryableAsync(); + var langKey = await AsyncExecuter.FirstOrDefaultAsync(keyQueryable.Where(a => a.ResourceName == res && a.Key == key)) + ?? await repoLangKey.InsertAsync(new LanguageKey { ResourceName = res, Key = key }, autoSave: false); + + var textQueryable = await repoLangText.GetQueryableAsync(); + var existingTexts = await AsyncExecuter.ToListAsync( + textQueryable.Where(a => a.ResourceName == res && a.Key == langKey.Key) + ); + + var langTextEn = existingTexts.FirstOrDefault(a => a.CultureName == cultureNameDefault) + ?? await repoLangText.InsertAsync(new LanguageText { ResourceName = res, Key = langKey.Key, CultureName = cultureNameDefault, Value = textEn }, autoSave: false); + + var langTextTr = existingTexts.FirstOrDefault(a => a.CultureName == LanguageCodes.Tr) + ?? await repoLangText.InsertAsync(new LanguageText { ResourceName = res, Key = langKey.Key, CultureName = LanguageCodes.Tr, Value = textTr }, autoSave: false); return langKey; } } - -