我有这个方法可以使用 IQueryiable 动态排序和过滤:
GridState<GreenPaperItem> state = null;
private async Task<GridData<GreenPaperItem>> LoadData(GridState<GreenPaperItem> state)
{
this.state = state;
var query = context.GreenPaperItems.AsQueryable();
if (state.FilterDefinitions != null && state.FilterDefinitions.Count() > 0)
{
foreach (var filter in state.FilterDefinitions)
query = query.Where(filter.GenerateFilterFunction());
}
if (state.SortDefinitions != null && state.SortDefinitions.Count() > 0)
{
foreach (var sort in state.SortDefinitions)
query = query.OrderBy(sort.SortFunc);
}
else
{
query = query.OrderBy(w => w.Date);
}
int count = query.Count();
var items = query.Skip(state.PageSize * state.Page).Take(state.PageSize)
.ToList<GreenPaperItem>();
GridData<GreenPaperItem> data = new()
{
Items = items,
TotalItems = count
};
return data;
}
但是 where 和 sort linq 方法只能获取字符串和表达式来返回 IQueryiable。方法内部的函数用红色下划线表示。如何使这项工作有效? 错误表示无法将
IEnumaerable<GreenPaperItem>
转换为 IQueryiable<GreenPaperItem>
。
而且它不能在运行时使用此代码进行翻译:
if (state.FilterDefinitions != null && state.FilterDefinitions.Count() > 0)
{
foreach (var filter in state.FilterDefinitions)
query = query.Where(it => filter.GenerateFilterFunction(null)(it));
}
if (state.SortDefinitions != null && state.SortDefinitions.Count() > 0)
{
foreach (var sort in state.SortDefinitions)
query = query.OrderBy(it => sort.SortFunc(it));
}
else
{
query = query.OrderBy(w => w.Date);
}
基于此post,它现在正在运行。但高级过滤仍然不起作用:
<MudDataGrid T="GreenPaperItem" ServerData="LoadData" Filterable="true" FilterMode="@DataGridFilterMode.ColumnFilterRow" @ref="grid">
<Columns>
<PropertyColumn TProperty="int" T="GreenPaperItem" Property="@(it => it.Id)"
Filterable="true">
</PropertyColumn>
<PropertyColumn TProperty="DateTime" T="GreenPaperItem" Property="@(it => it.Date)"
Filterable="true">
<FilterTemplate>
<MudIconButton OnClick="@OpenFilter" Icon="@_icon" Size="@Size.Small" />
<MudOverlay Visible="@_filterOpen" OnClick="@(() => _filterOpen = false)" />
<MudPopover Open="@_filterOpen" AnchorOrigin="Origin.BottomCenter" TransformOrigin="Origin.TopCenter" Style="width:600px">
<MudStack Row="true" Spacing="2" AlignItems="AlignItems.Center
" Justify="Justify.FlexStart">
<MudText>Between:</MudText>
<MudDatePicker @bind-Date="start" t Label="Start">
</MudDatePicker>
<MudDatePicker @bind-Date="end" Label="End">
</MudDatePicker>
<MudStack Row="true">
<MudButton OnClick="@(() => ClearFilterAsync(context))">Clear</MudButton>
<MudButton Color="@Color.Primary" OnClick="@(() => ApplyFilterAsync(context))">Filter</MudButton>
</MudStack>
</MudStack>
</MudPopover>
</FilterTemplate>
</PropertyColumn>
<PropertyColumn TProperty="string" T="GreenPaperItem" Property="@(it => it.Title)">
</PropertyColumn>
<TemplateColumn CellClass="d-flex justify-end">
<CellTemplate>
<MudIconButton Size="@Size.Small" Icon="@Icons.Material.Outlined.Edit" OnClick="@context.Actions.StartEditingItemAsync" />
</CellTemplate>
</TemplateColumn>
</Columns>
<PagerContent>
<MudDataGridPager T="GreenPaperItem"></MudDataGridPager>
</PagerContent>
</MudDataGrid>
代码:
@code {
MudDataGrid<GreenPaperItem> grid;
FilterDefinition<GreenPaperItem> _filterDefinition;
DateTime? start = DateTime.Today;
DateTime? end = DateTime.Today;
DateTime? filterStart = null;
DateTime? filterEnd = null;
string _icon = Icons.Material.Outlined.FilterAlt;
bool _filterOpen = false;
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
filterStart = start;
filterEnd = end;
_filterDefinition = new FilterDefinition<GreenPaperItem>
{
FilterFunction = x => x.Date.Date >= filterStart.Value.Date && x.Date.Date <= filterEnd.Value.Date
};
}
void OpenFilter()
{
_filterOpen = true;
}
private async Task ClearFilterAsync(FilterContext<GreenPaperItem> context)
{
filterStart = default(DateTime);
filterEnd = default(DateTime);
_icon = Icons.Material.Outlined.FilterAlt;
await context.Actions.ClearFilterAsync(_filterDefinition);
_filterOpen = false;
}
private async Task ApplyFilterAsync(FilterContext<GreenPaperItem> context)
{
filterStart = start;
filterEnd = end;
_icon = Icons.Material.Filled.FilterAlt;
await context.Actions.ApplyFilterAsync(_filterDefinition);
_filterOpen = false;
}
GridState<GreenPaperItem> state = null;
private async Task<GridData<GreenPaperItem>> LoadData(GridState<GreenPaperItem> state)
{
this.state = state;
var query = context.GreenPaperItems.AsQueryable();
if (state.FilterDefinitions != null && state.FilterDefinitions.Count() > 0)
{
foreach (var filter in state.FilterDefinitions)
{
var expression = FilterExpressionGenerator.GenerateExpression<GreenPaperItem>
(filter, new FilterOptions() { FilterCaseSensitivity = DataGridFilterCaseSensitivity.Default });
query = query.Where(expression);
}
}
if (state.SortDefinitions != null && state.SortDefinitions.Count() > 0)
{
foreach (var sort in state.SortDefinitions)
query = query.OrderBy($"{sort.SortBy} {(sort.Descending ? "descending" : "ascending")}");
}
else
{
query = query.OrderBy(w => w.Date);
}
bool? result = await dialogService.ShowMessageBox(
"Warning", query.ToQueryString(), yesText: "OK", cancelText: "Cancel");
int count = query.Count();
var items = query.Skip(state.PageSize * state.Page).Take(state.PageSize)
.ToList<GreenPaperItem>();
GridData<GreenPaperItem> data = new()
{
Items = items,
TotalItems = count
};
return data;
}
如何做到这一点?