环境设置见如何使用和https://limfx.pro相同的后端技术?
DBQueryService
是LimFx.Common包中的核心功能之一,它封装了方便的MongoDb查询功能,可以帮助开发者快速封装自己的service设计。
使用DBQueryService
又两种方法,一种是继承,一种是直接注入。笔者建议优先继承,因为继承使用可以更方便的创建mongodb索引,同时根据你的需要重写或进一步封装DBQueryService
的函数。
services.AddSingleton<DBQueryServices<SampleEmail>>(new DBQueryServices<SampleEmail>("mongodb://localhost:27017", "mongo", "email"));
图中直接注入了DBQueryService
,它的泛型类为SampleEmail
,这是mongodb中对应的模型类。构造函数接受的三个参数分别为连接字符串,数据库名,集合名。
注意,泛型类要求继承
Entity
类和ISearchable
接口
使用时直接注入使用即可,DBQueryService
的代码提示中又很详细的中文说明,这里把源码接口奉上
/// <summary>
/// Class which provide basic functions for database query
/// can be inherit by sepecific database service class.
/// </summary>
/// <typeparam name="T">Database Class</typeparam>
public interface IDBQueryServices<T> where T : Entity, ISearchAble
{
/// <summary>
/// 就是<strong>Builders<T>.Filter</strong>
/// </summary>
static FilterDefinitionBuilder<T> filterBuilder { get; } = Builders<T>.Filter;
/// <summary>
/// 数据库集合,用于自定义查询
/// </summary>
IMongoCollection<T> collection { get; }
/// <summary>
/// 获取满足特定条件的document个数
/// </summary>
/// <param name="filter">条件</param>
/// <returns>文档数</returns>
ValueTask<int> GetNumAsync(FilterDefinition<T> filter);
/// <summary>
/// 获取满足特定条件的document个数
/// </summary>
/// <param name="filter">条件</param>
/// <returns>文档数</returns>
ValueTask<int> GetNumAsync(Expression<Func<T, bool>> filter);
/// <summary>
/// 通过id获取实体
/// </summary>
/// <param name="Id">实体id</param>
/// <param name="filter">条件</param>
/// <returns></returns>
ValueTask<T> FindFirstAsync(Guid Id, FilterDefinition<T> filter = null);
/// <summary>
/// 获取符合条件的第一个实体的映射类
/// </summary>
/// <typeparam name="TProject">映射类</typeparam>
/// <param name="filter">条件</param>
/// <param name="projection">映射,相当于linq中select接受的lambda</param>
/// <returns>映射类</returns>
ValueTask<TProject> FindFirstAsync<TProject>(Expression<Func<T, bool>> filter, Expression<Func<T, TProject>> projection);
/// <summary>
/// 获取符合条件的第一个实体的映射类
/// </summary>
/// <typeparam name="TProject">映射类</typeparam>
/// <param name="filter">条件</param>
/// <param name="projection">映射,相当于linq中select接受的lambda</param>
/// <returns>映射类</returns>
ValueTask<TProject> FindFirstAsync<TProject>(FilterDefinition<T> filter, Expression<Func<T, TProject>> projection);
/// <summary>
/// 插入一个或多个实体<strong>请勿插入空值</strong>
/// </summary>
/// <param name="t">实体</param>
/// <returns></returns>
ValueTask AddAsync(params T[] t);
/// <summary>
/// 插入一个或多个实体<strong>请勿插入空值</strong>
/// </summary>
/// <param name="t">实体</param>
/// <returns></returns>
ValueTask AddAsync(List<T> t);
/// <summary>
/// 根据Id删除<strong>不是真的删除,仅仅把isdelete标记为删除</strong>
/// </summary>
/// <param name="id">目标实例id</param>
/// <returns></returns>
ValueTask DeleteAsync(params Guid[] id);
/// <summary>
/// 获取满足特定条件的一定数量的结果
/// </summary>
/// <typeparam name="TProject">映射的类型</typeparam>
/// <param name="projection">从实体类型获取映射类型的表达式</param>
/// <param name="page">页数</param>
/// <param name="pageSize">页长</param>
/// <param name="sortDefinition">排序方式</param>
/// <param name="filter">筛选条件</param>
/// <param name="query">搜索词</param>
/// <returns>查询结果</returns>
ValueTask<IEnumerable<TProject>> GetAsync<TProject>(
ProjectionDefinition<T, TProject> projection, int page = 0, int? pageSize = 10, SortDefinition<T> sortDefinition = null
, FilterDefinition<T> filter = null, string query = null);
/// <summary>
/// 获取满足特定条件的一定数量的结果
/// </summary>
/// <typeparam name="TProject">映射的类型</typeparam>
/// <param name="expression">从实体类型获取映射类型的表达式</param>
/// <param name="isDescending">是否逆序</param>
/// <param name="page">页数</param>
/// <param name="pageSize">页长</param>
/// <param name="orderBy">排序方式</param>
/// <param name="filter">筛选条件</param>
/// <param name="query">搜索词</param>
/// <returns>查询结果</returns>
ValueTask<IEnumerable<TProject>> GetAsync<TProject>(Expression<Func<T, TProject>> expression, int page = 0, int? pageSize = 10, string orderBy = "UpdateTime", bool isDescending = true, FilterDefinition<T> filter = null, string query = null);
/// <summary>
/// 获取满足特定条件的一定数量的结果
/// </summary>
/// <typeparam name="TProject">映射的类型</typeparam>
/// <param name="expression">从实体类型获取映射类型的表达式,相当于linq中select接受的lambda</param>
/// <param name="isDescending">是否逆序</param>
/// <param name="page">页数</param>
/// <param name="pageSize">页长</param>
/// <param name="orderBy">排序方式</param>
/// <param name="filter">筛选条件</param>
/// <param name="query">搜索词</param>
/// <returns>查询结果</returns>
ValueTask<IEnumerable<TProject>> GetAsync<TProject>(Expression<Func<T, TProject>> expression, Expression<Func<T, object>> orderBy, int page = 0, int? pageSize = 10, bool isDescending = true, FilterDefinition<T> filter = null, string query = null);
/// <summary>
/// 获取满足特定条件的一定数量的结果
/// </summary>
/// <typeparam name="TProject">映射的类型</typeparam>
/// <param name="expression">从实体类型获取映射类型的表达式,相当于linq中select接受的lambda</param>
/// <param name="isDescending">是否逆序</param>
/// <param name="page">页数</param>
/// <param name="pageSize">页长</param>
/// <param name="orderBy">排序方式</param>
/// <param name="filter">筛选条件</param>
/// <param name="query">搜索词</param>
/// <returns>查询结果</returns>
ValueTask<IEnumerable<TProject>> GetAsync<TProject>(Expression<Func<T, TProject>> expression, string orderBy, int page = 0, int? pageSize = 10, bool isDescending = true, Expression<Func<T, bool>> filter = null, string query = null);
/// <summary>
/// 搜索,并返回一定数量的结果
/// <strong>此方法已弃用,使用<code>GetAsync</code>代替之</strong>
/// </summary>
/// <typeparam name="TProject">映射的类型</typeparam>
/// <param name="expression">从实体类型获取映射类型的表达式,相当于linq中select接受的lambda</param>
/// <param name="query">搜索的关键词</param>
/// <param name="page">页数</param>
/// <param name="pageSize">页长</param>
/// <param name="orderBy">排序方式</param>
/// <param name="filter">筛选条件</param>
/// <returns>查询结果</returns>
[Obsolete]
ValueTask<IEnumerable<TProject>> SearchAsync<TProject>(Expression<Func<T, TProject>> expression, string query, int page = 0, int? pageSize = 10, string orderBy = "_id", FilterDefinition<T> filter = null);
/// <summary>
/// update某实体的特定几种属性
/// </summary>
/// <param name="id">update目标的id</param>
/// <param name="updateDefinition"></param>
/// <returns></returns>
ValueTask UpDateAsync(Guid id, UpdateDefinition<T> updateDefinition);
/// <summary>
/// update某实体的特定几种属性
/// </summary>
/// <param name="filter">用于确定被更新实例的filter</param>
/// <param name="updateDefinition"></param>
/// <returns></returns>
ValueTask UpDateAsync(FilterDefinition<T> filter, UpdateDefinition<T> updateDefinition);
/// <summary>
/// update某实体的特定几种属性
/// </summary>
/// <param name="filter">用于确定被更新实例的filter</param>
/// <param name="updateDefinition"></param>
/// <returns></returns>
ValueTask UpDateAsync(Expression<Func<T, bool>> filter, UpdateDefinition<T> updateDefinition);
/// <summary>
/// 是否存在满足特定条件的文档
/// </summary>
/// <param name="filter">筛选条件</param>
/// <returns></returns>
ValueTask<bool> AnyAsync(FilterDefinition<T> filter);
/// <summary>
/// 是否存在满足特定条件的文档
/// </summary>
/// <param name="filter">筛选条件</param>
/// <returns></returns>
ValueTask<bool> AnyAsync(Expression<Func<T, bool>> filter);
}
注:
DBQueryService
包含利用mongodb进行stringsearch的功能,因此要求泛型类继承ISearchable
接口,您可以把想要用于搜索的内容存于ISearchable
接口强制要求实现的SearchAbleString
中,例如:
>public string SearchAbleString { get => Name + "\n" + Description; set => _ = value; }
如果不需要搜索功能,可以使用DBQueryServiceSlim
代替DBQueryService
DBQueryService
中封装的所有查询都在数据库端完成
目前对DBQueryService
没有单独的benchmark结果,limfx的benchmark总结果见: LimFx的benchmark结果
是不是很简单?
喜欢的话点个赞吧~
本文章使用limfx的vsocde插件快速发布