上一篇文章(https://www.cnblogs.com/meowv/p/12913676.html)我们用Code-First的方式创建了博客所需的实体类,生成了数据库表,完成了对EF Core的封装。
本篇说一下自定义仓储的实现方式,其实在abp框架中已经默认给我们实现了默认的通用(泛型)仓储,IRepository<TEntity, TKey>,有着标准的CRUD操作,可以看:https://docs.abp.io/zh-Hans/abp/latest/Repositories 学习更多。
之所以实现自定义仓储,是因为abp没有给我们实现批量插入、更新的方法,这个是需要自己去扩展的。
既然是自定义仓储,那么就有了很高的自由度,我们可以任意发挥,可以接入第三方批量处理数据的库,可以接入Dapper操作等等,在这里贴一下微软官方推荐的一些EF Core的工具和扩展:https://docs.microsoft.com/zh-cn/ef/core/extensions/ 。
自定义仓储在.Domain领域层中创建仓储接口,IPostRepository、ICategoryRepository、ITagRepository、IPostTagRepository、IFriendLinkRepository,这里直接全部继承 IRepository<TEntity, TKey> 以使用已有的通用仓储功能。
可以转到IRepository<TEntity, TKey>接口定义看一下
看看abp对于仓储的介绍,如下:
IRepository<TEntity, TKey> 接口扩展了标准 IQueryable<TEntity> 你可以使用标准LINQ方法自由查询。但是,某些ORM提供程序或数据库系统可能不支持IQueryable接口。
ABP提供了 IBasicRepository<TEntity, TPrimaryKey> 和 IBasicRepository<TEntity> 接口来支持这样的场景。
你可以扩展这些接口(并可选择性地从BasicRepositoryBase派生)为你的实体创建自定义存储库。
依赖于 IBasicRepository 而不是依赖 IRepository 有一个优点, 即使它们不支持 IQueryable 也可以使用所有的数据源, 但主要的供应商, 像 Entity Framework, NHibernate 或 MongoDb 已经支持了 IQueryable。
因此, 使用 IRepository 是典型应用程序的 建议方法。但是可重用的模块开发人员可能会考虑使用 IBasicRepository 来支持广泛的数据源。
对于想要使用只读仓储提供了IReadOnlyRepository<TEntity, TKey> 与 IReadOnlyBasicRepository<Tentity, TKey>接口。
仓储接口类如下:
//IPostRepository.cs using Volo.Abp.Domain.Repositories; namespace Meowv.Blog.Domain.Blog.Repositories { /// <summary> /// IPostRepository /// </summary> public interface IPostRepository : IRepository<Post, int> { } } //ICategoryRepository.cs using Volo.Abp.Domain.Repositories; namespace Meowv.Blog.Domain.Blog.Repositories { /// <summary> /// ICategoryRepository /// </summary> public interface ICategoryRepository : IRepository<Category, int> { } } //ITagRepository.cs using System.Collections.Generic; using System.Threading.Tasks; using Volo.Abp.Domain.Repositories; namespace Meowv.Blog.Domain.Blog.Repositories { /// <summary> /// ITagRepository /// </summary> public interface ITagRepository : IRepository<Tag, int> { /// <summary> /// 批量插入 /// </summary> /// <param></param> /// <returns></returns> Task BulkInsertAsync(IEnumerable<Tag> tags); } } //IPostTagRepository.cs using System.Collections.Generic; using System.Threading.Tasks; using Volo.Abp.Domain.Repositories; namespace Meowv.Blog.Domain.Blog.Repositories { /// <summary> /// IPostTagRepository /// </summary> public interface IPostTagRepository : IRepository<PostTag, int> { /// <summary> /// 批量插入 /// </summary> /// <param></param> /// <returns></returns> Task BulkInsertAsync(IEnumerable<PostTag> postTags); } } //IFriendLinkRepository.cs using Volo.Abp.Domain.Repositories; namespace Meowv.Blog.Domain.Blog.Repositories { /// <summary> /// IFriendLinkRepository /// </summary> public interface IFriendLinkRepository : IRepository<FriendLink, int> { } }在ITagRepository和IPostTagRepository仓储接口中,我们添加了批量插入的方法。相对于的在我们的.EntityFrameworkCore层实现这些接口。
创建Repositories/Blog 文件夹,添加实现类:PostRepository、CategoryRepository、TagRepository、PostTagRepository、FriendLinkRepository。
不知道大家发现没有,我们的仓储接口以及实现,都是以Repository结尾的,这和我们的.Application应用服务层都以Service结尾是一个道理。
在自定义仓储的实现中,我们可以使用任意你想使用的数据访问工具,我们这里还是继续用Entity Framework Core,需要继承EfCoreRepository<TDbContext, TEntity, TKey>,和我们的仓储接口IXxxRepository。
EfCoreRepository默认实现了许多默认的方法,然后就可以直接使用 DbContext 来执行操作了。