Sort Foreign Key Locking Up
When I click on the Player foreign key column, the app freezes. I am using Dapper and SQLite.
@page "/Points"
<h3>Points</h3>
@using Golf.Quota.Services
@using Golf.Quota.Models
@using Golf.Quota.Services.Golf.Quota.Services
@using Golf.Quota.PlayerServices
@using Golf.Quota.GroupServices
@using Golf.Quota.PointServices
@using Syncfusion.Blazor
@using Syncfusion.Blazor.Buttons
@using Syncfusion.Blazor.Data
@using Syncfusion.Blazor.Grids
@using Syncfusion.Blazor.DropDowns
@using Syncfusion.Blazor.Popups
@using Syncfusion.Blazor.Inputs
@inject GlobalStateService GlobalStateService
@inject GroupService GroupService
@inject PlayerService PlayerService
@inject PointService PointService
<PageTitle>Points</PageTitle>
<div class="col-lg-12 control-section">
<div class="content-wrapper">
<div class="row">
<SfDialog @ref="Dialog" Width="300px" ShowCloseIcon="true" IsModal="true" @bind-Visible="@IsVisible">
<DialogTemplates>
<Content>
<div>@DialogMessage</div>
</Content>
</DialogTemplates>
<DialogButtons>
<DialogButton Content="OK" IsPrimary="true" OnClick="@OkClick" />
</DialogButtons>
</SfDialog>
<SfDropDownList TItem="Group"
TValue="int"
PopupHeight="350px"
PopupWidth="350px"
DataSource="@GroupList"
@bind-Value="GlobalStateService.SelectedGroupId"
FloatLabelType="FloatLabelType.Auto"
Placeholder="Select Group"
OnValueSelect="OnGroupChanged"
Enabled="true"
RowHeight="20">
<DropDownListEvents TItem="Group"
TValue="int"
OnValueSelect="@OnValueSelecthandler">
</DropDownListEvents>
<DropDownListFieldSettings Value="Id"
Text="Name">
</DropDownListFieldSettings>
</SfDropDownList>
</div>
</div>
</div>
<br />
<SfGrid DataSource="@FilteredPoints"
Toolbar="@(new List<string>() {"Edit", "Delete", "Update", "Cancel", "Search"})"
OnActionBegin="GridActionBegin"
OnActionComplete="GridActionComplete"
@bind-Value="GlobalStateService.SelectedGroupId"
EnableStickyHeader=true
AllowFiltering="true"
AllowSorting="true"
AllowResizing="true"
AllowGrouping="false"
EnableInfiniteScrolling="false"
AllowPaging="true"
Height="400"
RowHeight="20"
@attributes="@GridAttributes">
<GridEditSettings AllowAdding="true"
AllowEditing="true"
AllowDeleting="true"
Mode="EditMode.Normal"
ShowDeleteConfirmDialog="true"
ShowAddNewRow="true">
</GridEditSettings>
<GridPageSettings PageSizes="true"
PageSize="18">
</GridPageSettings>
<GridGroupSettings
EnableLazyLoading="false">
</GridGroupSettings>
<GridEvents OnActionBegin="GridActionBegin"
OnActionComplete="GridActionComplete"
TValue="Point">
</GridEvents>
<GridFilterSettings
Type="Syncfusion.Blazor.Grids.FilterType.Excel">
</GridFilterSettings>
<GridColumns>
<GridColumn Field="Id"
IsPrimaryKey="true"
Visible="false"/>
<GridColumn Field="PlayDate"
Format="yyyy-MM-dd"
Type="ColumnType.Date"
HeaderText="Play Date"
DefaultValue="GlobalStateService.LastPlayDate"
ValidationRules="@(new ValidationRules{ Required= true })" />
<GridForeignColumn ForeignDataSource="@FilteredPlayers"
HeaderText="Player"
Field=@nameof(Point.PlayerId)
AllowFiltering="true"
AllowSorting="true"
ForeignKeyField=@nameof(Player.Id)
ForeignKeyValue=@nameof(Player.FullName)
ValidationRules="@(new ValidationRules{ Required= true })">
<EditTemplate>
@{
var player = (context as Point).PlayerId;
}
<SfComboBox
TItem="Player"
TValue="int"
DataSource="@FilteredPlayers"
@bind-Value="@((context as Point).PlayerId)"
Placeholder="Select a player"
AllowFiltering="true">
<ComboBoxFieldSettings
Value="Id"
Text="FullName">
</ComboBoxFieldSettings>
</SfComboBox>
</EditTemplate>
</GridForeignColumn>
<GridColumn
Field="Points"
HeaderText="Points"
AllowFiltering="false"
ValidationRules="@(new ValidationRules{ Required= true })" />
</GridColumns>
</SfGrid>
<style>
.e-grid[disable="yes"] {
opacity: .5;
pointer-events: none;
-ms-touch-action: none;
touch-action: none;
cursor: no-drop;
}
.e-grid .e-dlg-content,
.e-grid .e-footer-content {
padding-top: 0px;
padding-bottom: 0px;
}
.e-grid .e-headercell {
font-weight: bold;
background-color: #f2f2f2; /* Light gray background */
}
</style>
@code {
private bool IsVisible { get; set; } = false;
private SfDialog Dialog;
private string DialogMessage;
private IEnumerable<Group> GroupList = new List<Group>();
private IEnumerable<Player> FilteredPlayers = new List<Player>();
private IEnumerable<Point> FilteredPoints = new List<Point>();
private Dictionary<string, object> GridAttributes { get; set; } = new Dictionary<string, object>();
protected override async Task OnInitializedAsync()
{
GroupList = await GroupService.GetAllGroupsAsync();
if (GlobalStateService.SelectedGroupId == 0)
{
GridAttributes.Add("disable", "yes");
}
else
{
FilteredPlayers = await PlayerService.GetPlayersByGroupIdAsync(GlobalStateService.SelectedGroupId);
FilteredPoints = await PointService.GetPointsByGroupIdAsync(GlobalStateService.SelectedGroupId);
}
// Console.WriteLine($"GroupList Count: {GroupList.Count()}"); // Debug line
StateHasChanged();
}
private async Task OnValueSelecthandler(SelectEventArgs<Group> args)
{
var selectedGroup = args.ItemData;
if (selectedGroup != null)
{
GlobalStateService.SelectedGroupId = selectedGroup.Id;
GlobalStateService.SelectedGroupName = selectedGroup.Name;
FilteredPlayers = await PlayerService.GetPlayersByGroupIdAsync(GlobalStateService.SelectedGroupId);
FilteredPoints = await PointService.GetPointsByGroupIdAsync(GlobalStateService.SelectedGroupId);
GridAttributes["disable"] = "no";
StateHasChanged();
}
}
private async Task GridActionBegin(Syncfusion.Blazor.Grids.ActionEventArgs<Point> args)
{
if (args.RequestType == Syncfusion.Blazor.Grids.Action.BeginEdit)
{
var point = args.Data as Point;
// Initialize or validate data before editing
}
else if (args.RequestType == Syncfusion.Blazor.Grids.Action.Add)
{
var point = args.Data as Point;
point.GroupId = GlobalStateService.SelectedGroupId;
if (GlobalStateService.LastPlayDate != null)
{
point.PlayDate = GlobalStateService.LastPlayDate;
}
}
else if (args.RequestType == Syncfusion.Blazor.Grids.Action.Delete)
{
var point = args.Data as Point;
await PointService.DeletePointAsync(point.Id);
}
}
private async Task GridActionComplete(Syncfusion.Blazor.Grids.ActionEventArgs<Point> args)
{
var point = args.Data as Point;
if (args.RequestType == Syncfusion.Blazor.Grids.Action.Save)
{
var isDuplicate = await PointService.CheckDuplicatePointAsync(point.PlayerId, point.PlayDate.Value, GlobalStateService.SelectedGroupId);
if ((isDuplicate) && (point.Id == 0))
{
// Show validation error
DialogMessage = "Duplicate record found: The same player cannot have points with the same play date.";
await Dialog.ShowAsync();
args.Cancel = true;
return;
}
if (point.Id == 0) // New record
{
point.GroupId = GlobalStateService.SelectedGroupId;
GlobalStateService.LastPlayDate = point.PlayDate.Value;
await PointService.InsertPointAsync(point);
}
else // Existing record
{
point.GroupId = GlobalStateService.SelectedGroupId;
await PointService.UpdatePointAsync(point);
}
}
}
private void OkClick()
{
Dialog.HideAsync();
}
}
Hi Larry,
Greetings from Syncfusion,
We have reviewed your query, and it seems that the issue occurs when clicking
the foreign column to sort, causing the application to freeze. However, we
created a simple sample and tested it with the latest version (27.2.5), but we
were unable to reproduce the issue on our end. Please refer to the attached
sample for your reference.
sample : https://blazorplayground.syncfusion.com/embed/hZLJsVDESSHMbndO?appbar=true&editor=true&result=true&errorlist=true&theme=bootstrap5
If the reported issue still reproduced, then kindly share the below details to validate further at our end.
- Share us the video demonstration of the issue with elaborately, it will be more useful to us.
- Could you please share how many records you are binding to the Grid
- After sorting, the UI freezes. Could you specify how long it takes for the freeze to occur (in minutes or seconds)? Also, do you observe any exceptions in the console during foreign sorting?
- Share us a simple issue replicating sample or try to modify the above mentioned sample.
The above-requested details will be very helpful for us to validate the reported query at our end and provide the solution as early as possible.
Regards,
Naveen Palanivel
I have 3474 points records. The Player sort takes longer during the video but without the video, it takes 35 seconds. I changed your example to have the same number of records, and it has the same slow Player sort as my app does. All other columns sort very quick, it's just the Foeiegn key column that is slow.
Attachment: Syncfusion_Sort_console_e784d910.zip
Based on the reported issue, we are already aware of the problem. We would like to inform you about the foreign key performance improvement. We have logged the scenario as 'Need to improve the performance while sorting the ForeignKey column' as an enhancement from our end. This feature will be included in our upcoming Volume 1, 2025 release.
You can now track the status of your request, review the proposed resolution timeline, and contact us for any further inquiries through this feedback link:
- 3 Replies
- 3 Participants
-
LA Larry
- Dec 6, 2024 02:23 PM UTC
- Dec 11, 2024 10:24 AM UTC