.NET 6开发TodoList应用怎么实现数据塑形
.NET 6开发TodoList应用怎么实现数据塑形
这篇文章主要介绍“.NET6开发TodoList应用怎么实现数据塑形”,在日常操作中,相信很多人在.NET6开发TodoList应用怎么实现数据塑形问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”.NET6开发TodoList应用怎么实现数据塑形”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
需求
在查询的场景中,还有一类需求不是很常见,就是在前端请求中指定返回的字段,所以关于搜索的最后一个主题我们就来演示一下关于数据塑形(Data Shaping)。
目标
实现数据塑形搜索请求。
原理与思路
对于数据塑形来说,我们需要定义一些接口和泛型类实现来完成通用的功能,然后修改对应的查询请求,实现具体的功能。
实现
定义通用接口和泛型类实现
IDataShaper.cs
usingSystem.Dynamic;namespaceTodoList.Application.Common.Interfaces;publicinterfaceIDataShaper<T>{IEnumerable<ExpandoObject>ShapeData(IEnumerable<T>entities,stringfieldString);ExpandoObjectShapeData(Tentity,stringfieldString);}
并实现通用的功能:
DataShaper.cs
usingSystem.Dynamic;usingSystem.Reflection;usingTodoList.Application.Common.Interfaces;namespaceTodoList.Application.Common;publicclassDataShaper<T>:IDataShaper<T>whereT:class{publicPropertyInfo[]Properties{get;set;}publicDataShaper(){Properties=typeof(T).GetProperties(BindingFlags.Public|BindingFlags.Instance);}publicIEnumerable<ExpandoObject>ShapeData(IEnumerable<T>entities,string?fieldString){varrequiredProperties=GetRequiredProperties(fieldString);returnGetData(entities,requiredProperties);}publicExpandoObjectShapeData(Tentity,string?fieldString){varrequiredProperties=GetRequiredProperties(fieldString);returnGetDataForEntity(entity,requiredProperties);}privateIEnumerable<PropertyInfo>GetRequiredProperties(string?fieldString){varrequiredProperties=newList<PropertyInfo>();if(!string.IsNullOrEmpty(fieldString)){varfields=fieldString.Split(',',StringSplitOptions.RemoveEmptyEntries);foreach(varfieldinfields){varproperty=Properties.FirstOrDefault(pi=>pi.Name.Equals(field.Trim(),StringComparison.InvariantCultureIgnoreCase));if(property==null){continue;}requiredProperties.Add(property);}}else{requiredProperties=Properties.ToList();}returnrequiredProperties;}privateIEnumerable<ExpandoObject>GetData(IEnumerable<T>entities,IEnumerable<PropertyInfo>requiredProperties){returnentities.Select(entity=>GetDataForEntity(entity,requiredProperties)).ToList();}privateExpandoObjectGetDataForEntity(Tentity,IEnumerable<PropertyInfo>requiredProperties){varshapedObject=newExpandoObject();foreach(varpropertyinrequiredProperties){varobjectPropertyValue=property.GetValue(entity);shapedObject.TryAdd(property.Name,objectPropertyValue);}returnshapedObject;}}
定义扩展方法
为了使我们的Handle方法调用链能够直接应用,我们在Application/Extensions中新增一个DataShaperExtensions:
DataShaperExtensions.cs
usingSystem.Dynamic;usingTodoList.Application.Common.Interfaces;namespaceTodoList.Application.Common.Extensions;publicstaticclassDataShaperExtensions{publicstaticIEnumerable<ExpandoObject>ShapeData<T>(thisIEnumerable<T>entities,IDataShaper<T>shaper,string?fieldString){returnshaper.ShapeData(entities,fieldString);}}
然后再对我们之前写的MappingExtensions静态类中添加一个方法:
MappingExtensions.cs
//省略其他...publicstaticPaginatedList<TDestination>PaginatedListFromEnumerable<TDestination>(thisIEnumerable<TDestination>entities,intpageNumber,intpageSize){returnPaginatedList<TDestination>.Create(entities,pageNumber,pageSize);}
添加依赖注入
在Application的DependencyInjection.cs中添加依赖注入:
DependencyInjection.cs
//省略其他services.AddScoped(typeof(IDataShaper<>),typeof(DataShaper<>));
修改查询请求和Controller接口
我们在上一篇文章实现排序的基础上增加一个字段用于指明数据塑形字段并对应修改Handle方法:
GetTodoItemsWithConditionQuery.cs
usingSystem.Dynamic;usingAutoMapper;usingAutoMapper.QueryableExtensions;usingMediatR;usingTodoList.Application.Common.Extensions;usingTodoList.Application.Common.Interfaces;usingTodoList.Application.Common.Mappings;usingTodoList.Application.Common.Models;usingTodoList.Application.TodoItems.Specs;usingTodoList.Domain.Entities;usingTodoList.Domain.Enums;namespaceTodoList.Application.TodoItems.Queries.GetTodoItems;publicclassGetTodoItemsWithConditionQuery:IRequest<PaginatedList<ExpandoObject>>{publicGuidListId{get;set;}publicbool?Done{get;set;}publicstring?Title{get;set;}//前端指明需要返回的字段publicstring?Fields{get;set;}publicPriorityLevel?PriorityLevel{get;set;}publicstring?SortOrder{get;set;}="title_asc";publicintPageNumber{get;set;}=1;publicintPageSize{get;set;}=10;}publicclassGetTodoItemsWithConditionQueryHandler:IRequestHandler<GetTodoItemsWithConditionQuery,PaginatedList<ExpandoObject>>{privatereadonlyIRepository<TodoItem>_repository;privatereadonlyIMapper_mapper;privatereadonlyIDataShaper<TodoItemDto>_shaper;publicGetTodoItemsWithConditionQueryHandler(IRepository<TodoItem>repository,IMappermapper,IDataShaper<TodoItemDto>shaper){_repository=repository;_mapper=mapper;_shaper=shaper;}publicTask<PaginatedList<ExpandoObject>>Handle(GetTodoItemsWithConditionQueryrequest,CancellationTokencancellationToken){varspec=newTodoItemSpec(request);returnTask.FromResult(_repository.GetAsQueryable(spec).ProjectTo<TodoItemDto>(_mapper.ConfigurationProvider).AsEnumerable()//进行数据塑形和分页返回.ShapeData(_shaper,request.Fields).PaginatedListFromEnumerable(request.PageNumber,request.PageSize));}}
对应修改Controller:
TodoItemController.cs
[HttpGet]publicasyncTask<ApiResponse<PaginatedList<ExpandoObject>>>GetTodoItemsWithCondition([FromQuery]GetTodoItemsWithConditionQueryquery){returnApiResponse<PaginatedList<ExpandoObject>>.Success(await_mediator.Send(query));}
验证
启动Api项目,执行查询TodoItem的请求:
请求
响应
我们再把之前讲到的过滤和搜索添加到请求里来:
请求
响应
到此,关于“.NET6开发TodoList应用怎么实现数据塑形”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!