LimFx的DBQuryService使用说明

环境设置见如何使用和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&lt;T&gt;.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插件快速发布