SelectAppService performans güçlendir

This commit is contained in:
Sedat Öztürk 2026-02-04 22:20:45 +03:00
parent 2aa5e99da2
commit 948ab358e4
2 changed files with 69 additions and 62 deletions

View file

@ -7,6 +7,7 @@ using Erp.Platform.OrganizationUnits;
using Erp.Platform.Queries;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp;
using Volo.Abp.Uow;
using static Erp.Platform.PlatformConsts;
namespace Erp.Platform.ListForms.Administration;
@ -50,6 +51,7 @@ public class ListFormQueryPreviewAppService : PlatformAppService
this.dynamicDataManager = dynamicDataManager;
}
[UnitOfWork]
public async Task<string> GetListFormSelectQueryAsync(string listFormCode)
{
//Izin logic process
@ -62,18 +64,21 @@ public class ListFormQueryPreviewAppService : PlatformAppService
//kullaniciya ait ListFormField verilerini al
var fields = await listFormFieldManager.GetUserListFormFields(listFormCode);
fields = fields.Where(a => a.CanRead).ToList();
// Performans: Filtrelemeyi Where ile yap, tek seferde ToList() çağır
var readableFields = fields.Where(a => a.CanRead).ToList();
//kullaniciya ait Server Customization verilerini al
var customizations = await listFormCustomizationManager.GetUsersServerCustomizations(listFormCode);
var (_, _, dataSourceType) = await dynamicDataManager.GetAsync(listForm.IsTenant, listForm.DataSourceCode);
selectQueryManager.PrepareQueries(listForm, fields, dataSourceType, customizations);
selectQueryManager.PrepareQueries(listForm, readableFields, dataSourceType, customizations);
return selectQueryManager.SelectQuery;
}
[UnitOfWork]
public async Task<string> GetListFormDataQueryAsync(string listFormCode, OperationEnum op)
{
var authType = op switch

View file

@ -162,18 +162,17 @@ public class ListFormSelectAppService : PlatformAppService, IListFormSelectAppSe
if (!string.IsNullOrEmpty(queryParams.Group) && !string.IsNullOrEmpty(selectQueryManager.GroupQuery))
{
//Console.WriteLine("===");
//Console.WriteLine(selectQueryManager.GroupQuery);
var data = await dynamicDataRepository.QueryAsync(selectQueryManager.GroupQuery, connectionString, param);
List<(string, int, List<dynamic>)> groups = [];
var dataQueryable = data.AsQueryable();
var groups = new List<(string, int, List<dynamic>)>(selectQueryManager.GroupTuples.Count);
for (int i = 0; i < selectQueryManager.GroupTuples.Count; i++)
{
var groupTuple = selectQueryManager.GroupTuples[i];
// var selectExpr = string.Join(",", selectQueryManager.GroupTuples.Take(i + 1).Select(a => $"{a.SelectExpr} as {a.SelectExpr}"));
var group = data.AsQueryable().GroupBy($"{groupTuple.SelectExpr}_Key").ToDynamicList();
var group = dataQueryable.GroupBy($"{groupTuple.SelectExpr}_Key").ToDynamicList();
groups.Add((groupTuple.SelectExpr, groupTuple.Index, group));
}
var items = SetGroupItems(groups, groups.First().Item3, 0);
var items = SetGroupItems(groups, groups[0].Item3, 0);
result.GroupCount = input.RequireGroupCount ? items.Count : -1;
result.Data = items;
@ -231,44 +230,45 @@ public class ListFormSelectAppService : PlatformAppService, IListFormSelectAppSe
if (!listForm.WidgetsJson.IsNullOrWhiteSpace())
{
var widgetList = JsonSerializer.Deserialize<WidgetEditDto[]>(listForm.WidgetsJson) ?? [];
foreach (var widget in widgetList.Where(w => w.IsActive))
var activeWidgets = widgetList.Where(w => w.IsActive && !string.IsNullOrWhiteSpace(w.SqlQuery)).ToList();
if (activeWidgets.Count == 0)
return Widgets;
// DataSource connection'ı bir kez al (performans)
var (dynamicDataRepository, connectionString, dataSourceType) = await dynamicDataManager.GetAsync(listForm.IsTenant, listForm.DataSourceCode);
foreach (var widget in activeWidgets)
{
if (!string.IsNullOrWhiteSpace(widget.SqlQuery))
var w = new WidgetDto
{
ColGap = widget.ColGap,
ColSpan = widget.ColSpan,
ClassName = widget.ClassName,
Items = []
};
var (dynamicDataRepository, connectionString, dataSourceType) = await dynamicDataManager.GetAsync(listForm.IsTenant, listForm.DataSourceCode);
var w = new WidgetDto
var items = await dynamicDataRepository.QueryAsync(widget.SqlQuery, connectionString);
if (items != null)
{
foreach (var item in items)
{
ColGap = widget.ColGap,
ColSpan = widget.ColSpan,
ClassName = widget.ClassName,
Items = []
};
var items = await dynamicDataRepository.QueryAsync(widget.SqlQuery, connectionString);
if (items != null)
{
foreach (var item in items)
if (item is IDictionary<string, object> dynamicItem)
{
if (item is IDictionary<string, object> dynamicItem)
w.Items.Add(new WidgetItemDto
{
w.Items.Add(new WidgetItemDto
{
Title = dynamicItem.ContainsKey(widget.Title) ? dynamicItem[widget.Title]?.ToString() : string.Empty,
Value = dynamicItem.ContainsKey(widget.Value) ? dynamicItem[widget.Value]?.ToString() : string.Empty,
Color = dynamicItem.ContainsKey(widget.Color) ? dynamicItem[widget.Color]?.ToString() : string.Empty,
Icon = dynamicItem.ContainsKey(widget.Icon) ? dynamicItem[widget.Icon]?.ToString() : string.Empty,
SubTitle = dynamicItem.ContainsKey(widget.SubTitle) ? dynamicItem[widget.SubTitle]?.ToString() : string.Empty,
OnClick = dynamicItem.ContainsKey(widget.OnClick) ? dynamicItem[widget.OnClick]?.ToString() : string.Empty,
});
}
Title = dynamicItem.ContainsKey(widget.Title) ? dynamicItem[widget.Title]?.ToString() : string.Empty,
Value = dynamicItem.ContainsKey(widget.Value) ? dynamicItem[widget.Value]?.ToString() : string.Empty,
Color = dynamicItem.ContainsKey(widget.Color) ? dynamicItem[widget.Color]?.ToString() : string.Empty,
Icon = dynamicItem.ContainsKey(widget.Icon) ? dynamicItem[widget.Icon]?.ToString() : string.Empty,
SubTitle = dynamicItem.ContainsKey(widget.SubTitle) ? dynamicItem[widget.SubTitle]?.ToString() : string.Empty,
OnClick = dynamicItem.ContainsKey(widget.OnClick) ? dynamicItem[widget.OnClick]?.ToString() : string.Empty,
});
}
}
Widgets.Add(w);
}
Widgets.Add(w);
}
}
@ -308,53 +308,55 @@ public class ListFormSelectAppService : PlatformAppService, IListFormSelectAppSe
var queryParameters = httpContextAccessor.HttpContext.Request.Query.ToDictionary(x => x.Key, x => x.Value);
var defaultFields = await defaultValueManager.GenerateDefaultValuesAsync(listForm, Enums.OperationEnum.Select, queryParameters: queryParameters);
// Performans: Dictionary ile hızlı lookup
var columnFormatsDict = result.ColumnFormats.ToDictionary(c => c.FieldName, c => c);
foreach (var field in defaultFields)
{
if (result.ColumnFormats.Any(a => a.FieldName == field.Key))
if (columnFormatsDict.TryGetValue(field.Key, out var columnFormat))
{
result.ColumnFormats.FirstOrDefault(a => a.FieldName == field.Key).DefaultValue = field.Value;
columnFormat.DefaultValue = field.Value;
}
}
if (!listForm.ExtraFilterJson.IsNullOrWhiteSpace())
{
var extraFilterList = JsonSerializer.Deserialize<ExtraFilterEditDto[]>(listForm.ExtraFilterJson) ?? [];
foreach (var extraFilter in extraFilterList)
var activeFilters = extraFilterList.Where(f => !string.IsNullOrWhiteSpace(f.SqlQuery)).ToList();
if (activeFilters.Count > 0)
{
if (!string.IsNullOrWhiteSpace(extraFilter.SqlQuery))
// DataSource connection'ı bir kez al (performans)
var (dynamicDataRepository, connectionString, dataSourceType) =
await dynamicDataManager.GetAsync(listForm.IsTenant, listForm.DataSourceCode);
// Dictionary ile hızlı lookup
var filtersDict = result.GridOptions.ExtraFilterDto.ToDictionary(f => f.FieldName, f => f);
foreach (var extraFilter in activeFilters)
{
var (dynamicDataRepository, connectionString, dataSourceType) =
await dynamicDataManager.GetAsync(listForm.IsTenant, listForm.DataSourceCode);
var items = await dynamicDataRepository.QueryAsync(extraFilter.SqlQuery, connectionString);
if (items != null)
if (items != null && filtersDict.TryGetValue(extraFilter.FieldName, out var filter))
{
var filters = result.GridOptions.ExtraFilterDto.ToList();
var filter = filters.FirstOrDefault(a => a.FieldName == extraFilter.FieldName);
var newItems = new List<ExtraFilterItemsDto>();
if (filter != null)
foreach (var item in items)
{
var newItems = new List<ExtraFilterItemsDto>();
foreach (var item in items)
if (item is IDictionary<string, object> dynamicItem)
{
if (item is IDictionary<string, object> dynamicItem)
newItems.Add(new ExtraFilterItemsDto
{
newItems.Add(new ExtraFilterItemsDto
{
Key = dynamicItem.ContainsKey("Key") ? dynamicItem["Key"]?.ToString() : null,
Value = dynamicItem.ContainsKey("Value") ? dynamicItem["Value"]?.ToString() : null
});
}
Key = dynamicItem.ContainsKey("Key") ? dynamicItem["Key"]?.ToString() : null,
Value = dynamicItem.ContainsKey("Value") ? dynamicItem["Value"]?.ToString() : null
});
}
filter.Items = newItems;
}
// 🔑 yeniden atıyoruz ki setter çalışsın
result.GridOptions.ExtraFilterDto = filters.ToArray();
filter.Items = newItems;
}
}
// 🔑 yeniden atıyoruz ki setter çalışsın
result.GridOptions.ExtraFilterDto = filtersDict.Values.ToArray();
}
}