一、使用示例:UsersManager.razor
注:TLog 相关内容参见 .NET 9.0 的 Blazor Web App 项目、Bootstrap Blazor 组件库、自定义日志 TLog 使用备忘-CSDN博客
@page "/Log/TLogManager"
<Table TItem="TLogEntity" DataService="new EfcoreDataService<TLogEntity>(TLog.TLogDb)"
AutoGenerateColumns=true HeaderStyle="TableHeaderStyle.Light"
ClickToSelect="true" ShowLoading="true" AllowResizing="true"
IsPagination="true" PageItemsSource="new int[] { 10, 15, 20, 25, 30, 60, 100 }" PageItems="15"
ShowToolbar="true" ShowDefaultButtons="false">
</Table>
@code {
}
二、数据服务 实现类:EfcoreDataService.cs
using BootstrapBlazor.Components;
using Microsoft.EntityFrameworkCore;
using System.Linq.Dynamic.Core;
namespace BlazorWebAppNet9Shared.Services;
/// <summary>
/// BootstrapBlazor Table组件 使用的注入 数据服务 实现类
/// </summary>
/// <typeparam name="TModel"></typeparam>
/// <param name="dbContext"></param>
public class EfcoreDataService<TModel>(DbContext dbContext) : DataServiceBase<TModel> where TModel : class
{
/* 查询 */
public override async Task<QueryData<TModel>> QueryAsync(QueryPageOptions options)
{
/* 模拟延时,以便能够看清楚 刷新 按钮转圈 */
await Task.Delay(200);
/* 不是翻页:刷新、改变每页条数、过虑,此时,清除跟踪(清除缓存)*/
if (!options.IsTriggerByPagination)
{
dbContext.ChangeTracker.Clear();
}
//构造查询
var efQuery = dbContext.Set<TModel>().AsQueryable();
/* 列过滤 Filter 处理:内置扩展方法 ToFilterFunc、ToFilterLambda 获得过滤条件 */
if (options.Filters.Count > 0)
{
efQuery = efQuery.Where(options.ToFilterLambda<TModel>());
}
/* 搜索:模糊搜索,Searchable = true 列与 SearchText */
if (options.Searches.Count > 0)
{
//逻辑关系使用 FilterLogic.Or
efQuery = efQuery.Where(options.Searches.GetFilterLambda<TModel>(FilterLogic.Or));
}
/* 高级搜索:精确 【测试 ???】 */
if (options.AdvanceSearches.Count > 0)
{
efQuery = efQuery.Where(options.AdvanceSearches.GetFilterLambda<TModel>(FilterLogic.And));
}
/* 排序 */
if (options.SortName != null && options.SortOrder != SortOrder.Unset)
{
efQuery = efQuery.OrderBy(options.SortName + " " + options.SortOrder);
}
else
{
/* 默认 Id 排序:如果 Id 的类型是 GUID ,则排序的结果不是 自然录入顺序 */
efQuery = efQuery.OrderBy("Id Asc");
}
//注:使用分页时,需要在外部处理 排序、过滤、搜索(因为传入的数据只有当前页的)
//使用 偏移分页(Offset pagination)方式
IEnumerable<TModel> items = await efQuery.Skip((options.PageIndex - 1) * options.PageItems).Take(options.PageItems).ToListAsync();
//返回查询结果、列表显示:设置为 true ,表示通知组件外部已处理,传入内容不需要再处理
return await Task.FromResult(new QueryData<TModel>() { Items = items, TotalCount = efQuery.Count(), IsSorted = true, IsFiltered = true, IsSearch = true, IsAdvanceSearch = true });
}
/* 新建:初始化 新建 实体,如无特殊初始化操作,可以不要,使用 Table 组件默认值。
public override Task<bool> AddAsync(TModel model)
{
return base.AddAsync(model);
//如果对新建的对象有初始处理,在这儿写代码操作,否则不需要重写本方法
return Task.FromResult(new ApplicationUser() { UserName = "新用户" });
} */
// 保存:新建或编辑
public override async Task<bool> SaveAsync(TModel model, ItemChangedType changedType)
{
//return base.SaveAsync(model, changedType);
bool re = false;
if (changedType == ItemChangedType.Add)
{
try
{
dbContext.Set<TModel>().Add(model);
var x = await dbContext.SaveChangesAsync();
re = x == 1;
}
catch (Exception)
{
re = false;
}
}
else
{
TModel oldItem = dbContext.Set<TModel>().First(x => x.Equals(model));
if (oldItem == null)
{
// 用户被其它人删除了
re = false;
}
else
{
try
{
Utility.Copy(model, oldItem);
var x = await dbContext.SaveChangesAsync();
re = x == 1;
}
catch (Exception)
{
re = false;
}
}
}
return await Task.FromResult(re);
}
/* 删除 */
public override async Task<bool> DeleteAsync(IEnumerable<TModel> models)
{
//return base.DeleteAsync(models);
/* 一次删除全部记录 */
try
{
dbContext.RemoveRange(models);
await dbContext.SaveChangesAsync();
return await Task.FromResult(true);
}
catch (Exception)
{
return await Task.FromResult(false);
}
}
}