在第1篇用的ToDoItem 继承的是BasicAggregateRoot, 但实际上企业应用,可能大部分实体,需要软删除,记录创建/修改/删除的人和时间. 来满足审计的要求
这就要用到FullAuditedEntity,
Dto和Entity要映射,如果没有映射会出现以下错误
2021-11-18 13:32:08.145 +08:00 [INF] Route matched with {action = "GetList", controller = "Announcement", area = "", page = ""}. Executing controller action with signature System.Threading.Tasks.Task`1[System.Collections.Generic.List`1[MetaBase.Platform.AnnouncementDto]] GetListAsync() on controller MetaBase.Platform.AnnouncementAppService (MetaBase.Platform.Application). 2021-11-18 13:32:08.152 +08:00 [ERR] ---------- RemoteServiceErrorInfo ---------- { "code": null, "message": "An internal error occurred during your request!", "details": null, "data": {}, "validationErrors": null } 2021-11-18 13:32:08.152 +08:00 [ERR] Error mapping types. Mapping types: Object -> List`1 System.Object -> System.Collections.Generic.List`1[[MetaBase.Platform.AnnouncementDto, MetaBase.Platform.Application.Contracts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] AutoMapper.AutoMapperMappingException: Error mapping types. Mapping types: Object -> List`1 System.Object -> System.Collections.Generic.List`1[[MetaBase.Platform.AnnouncementDto, MetaBase.Platform.Application.Contracts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] ---> AutoMapper.AutoMapperMappingException: Missing type map configuration or unsupported mapping. Mapping types: Announcement -> AnnouncementDto MetaBase.Platform.Announcement -> MetaBase.Platform.AnnouncementDto at lambda_method3301(Closure , Announcement , AnnouncementDto , ResolutionContext ) at lambda_method3300(Closure , Object , List`1 , ResolutionContext ) --- End of inner exception stack trace --- at lambda_method3300(Closure , Object , List`1 , ResolutionContext ) at Volo.Abp.ObjectMapping.DefaultObjectMapper.Map[TSource,TDestination](TSource source) in D:\ci\Jenkins\workspace\abp-framework-release\abp\framework\src\Volo.Abp.ObjectMapping\Volo\Abp\ObjectMapping\DefaultObjectMapper.cs:line 72 at MetaBase.Platform.AnnouncementAppService.GetListAsync() i
在Application项目的XXXApplicationAutoMapperProfile里添加Map, 重新生成HttpApi.Host 项目
CreateMap<AnnouncementDto, Announcement>().IgnoreAuditedObjectProperties(); //IgnoreAuditedObjectProperties 好像不加也可以 CreateMap<Announcement, AnnouncementDto>(); //加这句能从实体=>Dto
实体<=>Dto 这样要写2句也太麻烦了. 改成这样
CreateMap<Announcement, AnnouncementDto>().ReverseMap(); //双向映射
假如Dto和Entity的字段名,不一样, 假如我把Dto改成这样
public class AnnouncementDto { public Guid Id { get; set; } //Entity里默认用Id做主键,Dto则要显式指定guid public String Subject { get; set; } //标题Subject对应Entity.Title public String Content { get; set; } //公告内容对应Entity.ContentDesc public String ColumnCode { get; set; } //栏目编码 }
对应的Mapping就要这样写
CreateMap<Announcement, AnnouncementDto>() .ForMember(x=>x.Subject,options=>options.MapFrom(input=>input.Title)) .ForMember(x => x.Content, options => options.MapFrom(input => input.ContentDesc)) .ReverseMap();
在Application项目的实现方法里就可以用ObjectMapper.Map的方法来转换
public async Task<AnnouncementDto> GetAsync(Guid id) { var entity =await _Repo.GetAsync(id); return ObjectMapper.Map<Announcement, AnnouncementDto>(entity); } public async Task<List<AnnouncementDto>> GetListAsync() { var items = await _Repo.GetListAsync(); //entity list=> Dto list return ObjectMapper.Map<List<Announcement>, List<AnnouncementDto>>(items); }
WebAPI 方法命名的约定, Create/Get/Update/Delete ==> Post/Get/Put/Delete
我尝试加几个接口方法, GetAllListAysnc=> /List 去掉了All , GetAnyList2Async =-> any-list2
假如不想自己写增删查改的接口代码,可以接口继承 :ICrudAppService<XXXDto,Guid>, 实现类实现: CrudAppService<xxx实体,xxxDTO,Guid>,
注意Dto 不用定义guid的 Id字段, 要继承 AuditedEntityDto<Guid> 否则会出现这个错误
错误 CS0311 类型“MetaBase.Platform.AnnouncementDto”不能用作泛型类型或方法“CrudAppService<TEntity, TEntityDto, TKey>”中的类型参数“TEntityDto”。
没有从“MetaBase.Platform.AnnouncementDto”到“Volo.Abp.Application.Dtos.IEntityDto<System.Guid>”的隐式引用转换。
public class AnnouncementDto:AuditedEntityDto<Guid> { public Guid Id { get; set; } //CrudAppService 要去掉 public String Subject { get; set; } //标题Subject对应Entity.Title public String Content { get; set; } //公告内容对应Entity.ContentDesc public String ColumnCode { get; set; } //栏目编码 }
CrudAppService 实现的GetList的方法,是传入分页的 PagedAndSortedResultRequestDto ,返回PageResultDto<xxx>
PagedAndSortedResultRequestDto psrDto = new PagedAndSortedResultRequestDto() { SkipCount = 0, MaxResultCount = 5 }; annItems = (List<AnnouncementDto>)(await annService.GetListAsync(psrDto)).Items;
查询结果是这样的
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?