上篇文章完成了文章增删改的接口和友情连接列表的接口,本篇继续。html
善于思考的同窗确定发现,在执行增删改操做后,Redis缓存中的数据仍是存在的,也就意味着查询接口返回的数据仍是旧的,因此在写接口以前,先完成一下清缓存的操做。前端
移除缓存我这里找了一个新的包:Caching.CSRedis
,选他是由于微软的包Microsoft.Extensions.Caching.StackExchangeRedis
没有给咱们实现批量删除的功能。git
Caching.CSRedis
开源地址,https://github.com/2881099/csredis 在这不作过多介绍,感兴趣的本身去看。github
在.Application.Caching
层添加包Caching.CSRedis
,Install-Package Caching.CSRedis
,而后在模块类MeowvBlogApplicationCachingModule
中进行配置。redis
//MeowvBlogApplicationCachingModule.cs ... public override void ConfigureServices(ServiceConfigurationContext context) { ... var csredis = new CSRedis.CSRedisClient(AppSettings.Caching.RedisConnectionString); RedisHelper.Initialization(csredis); context.Services.AddSingleton<IDistributedCache>(new CSRedisCache(RedisHelper.Instance)); } ...
直接新建一个移除缓存的接口:ICacheRemoveService
,添加移除缓存的方法RemoveAsync()
。代码较少,能够直接写在缓存基类CachingServiceBase
中。数据库
public interface ICacheRemoveService { /// <summary> /// 移除缓存 /// </summary> /// <param name="key"></param> /// <param name="cursor"></param> /// <returns></returns> Task RemoveAsync(string key, int cursor = 0); }
而后能够在基类中实现这个接口。数组
public async Task RemoveAsync(string key, int cursor = 0) { var scan = await RedisHelper.ScanAsync(cursor); var keys = scan.Items; if (keys.Any() && key.IsNotNullOrEmpty()) { keys = keys.Where(x => x.StartsWith(key)).ToArray(); await RedisHelper.DelAsync(keys); } }
简单说一下这个操做过程,使用ScanAsync()
获取到全部的Redis key值,返回的是一个string数组,而后根据参数找到符合此前缀的全部key,最后调用DelAsync(keys)
删除缓存。缓存
在须要有移除缓存功能的接口上继承ICacheRemoveService
,这里就是IBlogCacheService
。app
//IBlogCacheService.cs namespace Meowv.Blog.Application.Caching.Blog { public partial interface IBlogCacheService : ICacheRemoveService { } }
在基类中已经实现了这个接口,因此如今全部继承基类的缓存实现类均可以调用移除缓存方法了。async
在MeowvBlogConsts
中添加缓存前缀的常量。
//MeowvBlogConsts.cs /// <summary> /// 缓存前缀 /// </summary> public static class CachePrefix { public const string Authorize = "Authorize"; public const string Blog = "Blog"; public const string Blog_Post = Blog + ":Post"; public const string Blog_Tag = Blog + ":Tag"; public const string Blog_Category = Blog + ":Category"; public const string Blog_FriendLink = Blog + ":FriendLink"; }
而后在BlogService.Admin.cs
服务执行增删改后调用移除缓存的方法。
//BlogService.Admin.cs // 执行清除缓存操做 await _blogCacheService.RemoveAsync(CachePrefix.Blog_Post);
由于是小项目,采用这种策略直接删除缓存,这样就搞定了当在执行增删改操做后,前台接口能够实时查询出最后的结果。
当咱们修改文章数据的时候,是须要把当前数据库中的数据带出来显示在界面上的,由于有可能只是个别地方须要修改,因此这还须要一个查询文章详情的接口,固然这里的详情和前端的是不同的,这里是须要根据Id主键去查询。
添加模型类PostForAdminDto.cs
,直接继承PostDto
,而后添加一个Tags列表就行,==,好像和上一篇文章中的EditPostInput
字段是如出一辙的。顺手将EditPostInput
改一下吧,具体代码以下:
//PostForAdminDto.cs using System.Collections.Generic; namespace Meowv.Blog.Application.Contracts.Blog { public class PostForAdminDto : PostDto { /// <summary> /// 标签列表 /// </summary> public IEnumerable<string> Tags { get; set; } } } //EditPostInput.cs namespace Meowv.Blog.Application.Contracts.Blog.Params { public class EditPostInput : PostForAdminDto { } }
在IBlogService.Admin.cs
中添加接口。
/// <summary> /// 获取文章详情 /// </summary> /// <param name="id"></param> /// <returns></returns> Task<ServiceResult<PostForAdminDto>> GetPostForAdminAsync(int id);
实现这个接口。
/// <summary> /// 获取文章详情 /// </summary> /// <param name="id"></param> /// <returns></returns> public async Task<ServiceResult<PostForAdminDto>> GetPostForAdminAsync(int id) { var result = new ServiceResult<PostForAdminDto>(); var post = await _postRepository.GetAsync(id); var tags = from post_tags in await _postTagRepository.GetListAsync() join tag in await _tagRepository.GetListAsync() on post_tags.TagId equals tag.Id where post_tags.PostId.Equals(post.Id) select tag.TagName; var detail = ObjectMapper.Map<Post, PostForAdminDto>(post); detail.Tags = tags; detail.Url = post.Url.Split("/").Where(x => !string.IsNullOrEmpty(x)).Last(); result.IsSuccess(detail); return result; }
先根据Id查出文章数据,再经过联合查询找出标签数据。
CreateMap<Post, PostForAdminDto>().ForMember(x => x.Tags, opt => opt.Ignore());
新建一条AutoMapper配置,将Post
转换成PostForAdminDto
,忽略Tags。
而后将查出来的标签、Url赋值给DTO,输出便可。在BlogController.Admin
中添加API。
/// <summary> /// 获取文章详情 /// </summary> /// <param name="id"></param> /// <returns></returns> [HttpGet] [Authorize] [Route("admin/post")] [ApiExplorerSettings(GroupName = Grouping.GroupName_v2)] public async Task<ServiceResult<PostForAdminDto>> GetPostForAdminAsync([Required] int id) { return await _blogService.GetPostForAdminAsync(id); }
至此,完成了关于文章的全部接口。
接下来按照以上方式依次完成分类、标签、友链的增删改查接口,我以为若是你有跟着我一块儿作,剩下的能够本身完成。
开源地址:https://github.com/Meowv/Blog/tree/blog_tutorial
搭配下方课程学习更佳 ↓ ↓ ↓