We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
我这边开发时,生成的应用还需要提供出接口供前端访问,这里基于这个需求和聚合根的特点,提供一个案例供大家参考:
首先是分页查询的入参:
/// <summary> /// 分页查询输入 /// </summary> public class PagedInput { /// <summary> /// 过滤条件 /// </summary> public DynamicFilterInfo? Filter { get; set; } /// <summary> /// 页码 /// </summary> public int Page { get; set; } /// <summary> /// 分页数 /// </summary> public int Size { get; set; } /// <summary> /// 排序 /// </summary> public string? OrderBy { get; set; } /// <summary> /// 是否正序 /// </summary> public bool Asc { get; set; } /// <summary> /// 包含的导航属性,如果一对多关系,需要包含多级导航属性用逗号分隔 /// </summary> public string[]? Include { get; set; } }
返回内容就比较简单了:
/// <summary> /// 分页查询结果 /// </summary> public class PagedOutput<TEntity> where TEntity : class { /// <summary> /// 总数 /// </summary> public long Total { get; set; } /// <summary> /// 分页数据 /// </summary> public List<TEntity> Data { get; set; } }
然后控制器设置一个 EntityControllerBase 方便其他聚合根实体对外公开接口时继承:
public class EntityControllerBase<TEntity, TKey>(IAggregateRootRepository<TEntity> repository) where TEntity : class, IEntity<TKey> { /// <summary> /// 查询 /// </summary> [HttpGet] public Task<TEntity> GetAsync(TKey id, CancellationToken cancellationToken) => repository.Select.Where(t => t.Id.Equals(id)).FirstAsync(cancellationToken); /// <summary> /// 分页查询 /// </summary> [HttpPost] public Task<PagedOutput<TEntity>> GetPagedAsync([FromBody] PagedInput input, CancellationToken cancellationToken) { var select = repository.Select; if (input.Filter != null) { select = select.WhereDynamicFilter(input.Filter); } if (input.Include is { Length: > 0 }) { foreach (var includeProperty in input.Include) { if (string.IsNullOrWhiteSpace(includeProperty)) continue; var includeProperties = includeProperty.Split(","); // includeProperties 长度不固定,循环构造表达式树获取内容 Expression<Action<ISelect<object>>> exp = null; for (var i = includeProperties.Length - 1; i > 0; i--) { // 创建一个表示输入参数的参数表达式 var parameter = Expression.Parameter(typeof(ISelect<object>), "then" + i); if (exp == null) { // 获取 IncludeByPropertyName 方法的 MethodInfo var methodInfo = typeof(ISelect<object>).GetMethod("IncludeByPropertyName", [typeof(string)]); var propertyName = Expression.Constant(includeProperties[i]); var methodCall = Expression.Call(parameter, methodInfo, propertyName); // 创建一个带有输入参数和方法调用的 Lambda 表达式 exp = Expression.Lambda<Action<ISelect<object>>>(methodCall, parameter); } else { // 获取 IncludeByPropertyName 方法的 MethodInfo var methodInfo = typeof(ISelect<object>).GetMethod("IncludeByPropertyName", [typeof(string), typeof(Expression<Action<ISelect<object>>>)]); var propertyName = Expression.Constant(includeProperties[i]); var methodCall = Expression.Call(parameter, methodInfo, propertyName, exp); // 创建一个带有输入参数和方法调用的 Lambda 表达式 exp = Expression.Lambda<Action<ISelect<object>>>(methodCall, parameter); } } select = exp == null ? select.IncludeByPropertyName(includeProperties[0]) : select.IncludeByPropertyName(includeProperties[0], exp); } } if (!string.IsNullOrEmpty(input.OrderBy)) { select = select.OrderBy(input.OrderBy, input.Asc); } return select.Count(out var total) .Page(Math.Max(input.Page, 1), Math.Min(Math.Max(input.Size, 1), 1000)) .ToListAsync(cancellationToken) .ContinueWith(t => new PagedOutput<TEntity> { Total = total, Data = t.Result }, cancellationToken); } /// <summary> /// 新增 /// </summary> [HttpPost] public Task<TEntity> AddAsync([FromBody] TEntity entity, CancellationToken cancellationToken) => repository.InsertAsync(entity, cancellationToken); /// <summary> /// 删除 /// </summary> [HttpDelete] public Task<int> DeleteAsync(TKey id, CancellationToken cancellationToken) => repository.DeleteAsync(t => t.Id.Equals(id), cancellationToken); /// <summary> /// 更新 /// </summary> [HttpPost] public Task<int> UpdateAsync([FromBody] TEntity entity, CancellationToken cancellationToken) => repository.UpdateDiy.SetSource(entity).ExecuteAffrowsAsync(cancellationToken); /// <summary> /// 批量新增 /// </summary> [HttpPost] public async Task<int> AddMultipleAsync([FromBody] TEntity[] entities, CancellationToken cancellationToken) { var count = 0; foreach (var entity in entities) { await repository.InsertAsync(entity, cancellationToken); count++; } return count; } /// <summary> /// 批量删除 /// </summary> [HttpDelete] public Task<int> DeleteMultipleAsync(TKey[] id, CancellationToken cancellationToken) => repository.DeleteAsync(t => id.Contains(t.Id), cancellationToken); /// <summary> /// 批量更新 /// </summary> [HttpPost] public Task<int> UpdateMultipleAsync([FromBody] TEntity[] entities, CancellationToken cancellationToken) => repository.UpdateDiy.SetSource(entities).ExecuteAffrowsAsync(cancellationToken); }
例如我有个 Component 实体,对外公开接口,则创建一个 ComponentController 继承 EntityControllerBase:
[Route("api/[controller]/[action]")] public class ComponentController(IAggregateRootRepository<Component> repository) : EntityControllerBase<Component, long>(repository) { }
The text was updated successfully, but these errors were encountered:
主要是分页查询拓展了一下 Include 属性,这里是分页查询 Form 表单的一个入参示例:
{ "filter": { "logic": "And", "filters": [ { "field": "id", "operator": "GreaterThanOrEqual", "value": 1 } ] }, "page": 1, "size": 10, "orderBy": "id", "asc": true, "include": [ "formGroups", "formGroups,warehouse", "formGroups,warehouse.project", "formItems", "formItems,formItemProps", "formItems,formItemProps,componentProp", "formItems,formItemProps,componentProp.component" ] }
Sorry, something went wrong.
有想法可以直接PR进来
No branches or pull requests
我这边开发时,生成的应用还需要提供出接口供前端访问,这里基于这个需求和聚合根的特点,提供一个案例供大家参考:
首先是分页查询的入参:
返回内容就比较简单了:
然后控制器设置一个 EntityControllerBase 方便其他聚合根实体对外公开接口时继承:
例如我有个 Component 实体,对外公开接口,则创建一个 ComponentController 继承 EntityControllerBase:
The text was updated successfully, but these errors were encountered: