I have a datagrid with DynamicData set up as in the example on Blazor DataGrid supports dynamic data sources. However i've also implemented LoadData so it only loads the page an no more since loading the full table is very slow. I want to use a DataFilter since I find the inline filters on the Datagrid quite ugly.
You can't use the dynamic Linq coming from the DataFilter since that expects Dictionary<string, object?>
and what I'm getting from the context is my own Entity-Attribute-Value setup. I can't convert it right away since entity framework doesn't accept certain methods I need to convert the objects into a row and thus I have to pull the entire table into memory, which again is slow. Also you cant apply paging before filtering the data.
<RadzenStack Orientation="Orientation.Horizontal" Gap="0.5rem" AlignItems="AlignItems.Center" Class="rz-p-4 rz-border-radius-1" Style="border: var(--rz-grid-cell-border);">
<RadzenCheckBox @bind-Value="@_auto" Name="auto" />
<RadzenLabel Text="Auto filter" Component="auto" Class="rz-me-6" />
<RadzenButton Text="Apply Filter" Click="@(args => _dataFilter!.Filter())" Disabled="@_auto" />
</RadzenStack>
<RadzenDataFilter @ref="_dataFilter" Auto="true" TItem="Dictionary<string, object?>" ViewChanged=@(view => _crudGrid!.Reload())>
<Properties>
@foreach (var column in _columns!.Where(x => x.Value != null))
{
<RadzenDataFilterProperty TItem="Dictionary<string, object?>" Property="@GetColumnPropertyExpression(column.Key, column.Value)" Title="@_fieldLookup![column.Key].Description" Type="@column.Value" />
}
</Properties>
</RadzenDataFilter>
I've come up with 3 possible avenues to proceed.
- Apply the .Filters of the DataFilter to the processed data in the DataGrid but i don't see any facility for that
- Write my own implementation of filtering the data
- Use the filter buttons on the DataGrid anyway
I've started on point 2 but it is very hard so I wanted to know if I'm going in the right direction or if there is another angle i might use
private void LoadPage(LoadDataArgs args)
{
_refreshingData = true;
PortalContext context = _contextFactory.CreateDbContext();
IQueryable<Item> query = context
.Items
.AsNoTracking()
.Include(x => x.ItemFields)
.ThenInclude(x => x.ArtifactField)
.Where(x => x.Artifact == _artifact);
query = query.Where(x => x.IsDeleted == _showDeleted);
IOrderedQueryable<Item>? orderedQuery = null;
var gridSort = _crudGrid!.ColumnsCollection.Select(x => new GridSort(x.Property, x.OrderIndex, x.SortOrder)).Where(x => x.SortOrder != null).OrderBy(x => x.SortIndex).ToList();
if (gridSort.Any())
{
foreach (var sorting in gridSort)
{
if (sorting == gridSort[0])
{
if (sorting.SortOrder == SortOrder.Ascending)
{
orderedQuery = query.OrderBy(i =>
i.ItemFields
.Where(f => f.ArtifactFieldId.ToString() == sorting.ColumnName)
.Select(f => new object[] { f.ValueBit, f.ValueDateTime, f.ValueDecimal, f.ValueInt, f.ValueString, f.ValueStringMax }
.FirstOrDefault(v => v != null))
.FirstOrDefault());
}
else
{
orderedQuery = query.OrderByDescending(i =>
i.ItemFields
.Where(f => f.ArtifactFieldId.ToString() == sorting.ColumnName)
.Select(f => new object[] { f.ValueBit, f.ValueDateTime, f.ValueDecimal, f.ValueInt, f.ValueString, f.ValueStringMax }
.FirstOrDefault(v => v != null))
.FirstOrDefault());
}
}
else
{
if (sorting.SortOrder == SortOrder.Ascending)
{
orderedQuery = orderedQuery.ThenBy(i =>
i.ItemFields
.Where(f => f.ArtifactFieldId.ToString() == sorting.ColumnName)
.Select(f => new object[] { f.ValueBit, f.ValueDateTime, f.ValueDecimal, f.ValueInt, f.ValueString, f.ValueStringMax }
.FirstOrDefault(v => v != null))
.FirstOrDefault());
}
else
{
orderedQuery = orderedQuery.ThenByDescending(i =>
i.ItemFields
.Where(f => f.ArtifactFieldId.ToString() == sorting.ColumnName)
.Select(f => new object[] { f.ValueBit, f.ValueDateTime, f.ValueDecimal, f.ValueInt, f.ValueString, f.ValueStringMax }
.FirstOrDefault(v => v != null))
.FirstOrDefault());
}
}
}
query = orderedQuery;
}
if (_dataFilter is not null && _dataFilter!.Filters.Any())
{
// ?
}
query = query.Skip(args.Skip.Value).Take(args.Top.Value);
_items = query!.ToList();
_count = _items.Count;
_data = query!.Select(x => CreateRowFromItem(x, _columns, _parentsLookup, _artifactRelations, _fieldLookup)).ToList();
_refreshingData = false;
}