烟笼寒水月笼纱 發表於 2023-4-9 18:53:00

.NET Core MongoDB数据仓储和工作单元模式封装

<h2>前言</h2>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;上一章我们把系统所需要的MongoDB集合设计好了,这一章我们的主要任务是使用.NET Core应用程序连接MongoDB并且封装MongoDB数据仓储和工作单元模式,因为本章内容涵盖的有点多关于仓储和工作单元的使用就放到下一章节中讲解了。仓储模式(Repository&nbsp;)带来的好处是一套代码可以适用于多个类,把常用的CRUD通用方法抽象出来通过接口形式集中管理,从而解除业务逻辑层与数据访问层之间的耦合,使业务逻辑层在存储、访问数据库时无须关心数据的来源及存储方式。工作单元模式(UnitOfWork)它是用来维护一个由已经被业务修改(如增加、删除和更新等)的业务对象组成的列表,跨多个请求的业务,统一管理事务,统一提交从而保障事物一致性的作用。</p>
<h2>MongoDB从入门到实战的相关教程</h2>
<p>MongoDB从入门到实战之MongoDB简介👉</p>
<p>MongoDB从入门到实战之MongoDB快速入门👉</p>
<p>MongoDB从入门到实战之Docker快速安装MongoDB👉</p>
<p>MongoDB从入门到实战之MongoDB工作常用操作命令👉</p>
<p>MongoDB从入门到实战之.NET Core使用MongoDB开发ToDoList系统(1)-后端项目框架搭建👉</p>
<p>MongoDB从入门到实战之.NET Core使用MongoDB开发ToDoList系统(2)-Swagger框架集成👉</p>
<p>MongoDB从入门到实战之.NET Core使用MongoDB开发ToDoList系统(3)-系统数据集合设计👉</p>
<p>MongoDB从入门到实战之.NET Core使用MongoDB开发ToDoList系统(4)-MongoDB数据仓储和工作单元模式封装👉</p>
<h2>YyFlight.ToDoList项目源码地址</h2>
<p><span style="color: rgba(255, 0, 0, 1)"><strong>欢迎各位看官老爷review,有帮助的别忘了给我个Star哦💖!!!</strong></span></p>
<blockquote>
<p>GitHub地址:https://github.com/YSGStudyHards/YyFlight.ToDoList</p>
<p>MongoRepository地址:https://github.com/YSGStudyHards/YyFlight.ToDoList/tree/main/Repository/Repository</p>
</blockquote>
<h2>MongoDB事务使用前提说明</h2>
<p>参阅MongoDB的事务</p>
<p><strong>说明:</strong></p>
<blockquote>
<p>MongoDB单机服务器不支持事务【使用MongoDB事务会报错:Standalone servers do not support transactions】,只有在集群情况下才支持事务,因为博主接下来都是在单机环境下操作,所以无法来演示Mongo事务操作,但是方法都已经是封装好了的,大家可以自己搭建集群实操。</p>
</blockquote>
<p><strong>原因:</strong></p>
<blockquote>
<p>MongoDB在使用分布式事务时需要进行多节点之间的协调和通信,而单机环境下无法实现这样的分布式协调和通信机制。但是,在MongoDB部署为一个集群(cluster)后,将多个计算机连接为一个整体,通过协调和通信机制实现了分布式事务的正常使用。从数据一致性和可靠性的角度来看,在分布式系统中实现事务处理是至关重要的。而在单机环境下不支持事务,只有在集群情况下才支持事务的设计方式是为了保证数据一致性和可靠性,并且也符合分布式系统的设计思想。</p>
</blockquote>
<h2>MongoDB.Driver驱动安装</h2>
<h3>1、直接命令自动安装</h3>
<div class="cnblogs_code">
<pre>Install-Package MongoDB.Driver</pre>
</div>
<h3>2、搜索Nuget手动安装</h3>
<p><img src="https://img2023.cnblogs.com/blog/1336199/202303/1336199-20230301003335511-1864259395.png" alt="" loading="lazy"></p>
<h2>MongoSettings数据库连接配置</h2>
<p>前往appsettings.json文件中配置Mongo数据库信息:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">MongoSettings</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: {
    </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Connection</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">mongodb://root:123456@local:27017/yyflight_todolist?authSource=admin</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">MongoDB连接字符串</span>
    <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">DatabaseName</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">yyflight_todolist</span><span style="color: rgba(128, 0, 0, 1)">"</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">MongoDB数据库名称</span>
}</pre>
</div>
<h2>定义单例的MongoClient</h2>
<blockquote>
<p>基于MongoDB的最佳实践对于MongoClient最好设置为单例注入,因为在MongoDB.Driver中MongoClient已经被设计为线程安全可以被多线程共享,这样可还以避免反复实例化MongoClient带来的开销,避免在极端情况下的性能低下。</p>
<p>我们这里设计一个MongoConnection类,用于包裹这个MongoClient,然后将其以单例模式注入IoC容器中。</p>
</blockquote>
<h3>定义IMongoConnection接口</h3>
<div class="cnblogs_code">
<pre>    <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">interface</span><span style="color: rgba(0, 0, 0, 1)"> IMongoConnection
    {
      </span><span style="color: rgba(0, 0, 255, 1)">public</span> MongoClient MongoDBClient { <span style="color: rgba(0, 0, 255, 1)">get</span>; <span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">; }
      </span><span style="color: rgba(0, 0, 255, 1)">public</span> IMongoDatabase DatabaseName { <span style="color: rgba(0, 0, 255, 1)">get</span>; <span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">; }
    }</span></pre>
</div>
<h3>定义MongoConnection类</h3>
<div class="cnblogs_code">
<pre>    <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> MongoConnection : IMongoConnection
    {
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">基于MongoDB的最佳实践对于MongoClient最好设置为单例注入,因为在MongoDB.Driver中MongoClient已经被设计为线程安全可以被多线程共享,这样可还以避免反复实例化MongoClient带来的开销,避免在极端情况下的性能低下。
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">我们这里设计一个MongoConnection类,用于包裹这个MongoClient,然后将其以单例模式注入IoC容器中。</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> MongoClient MongoDBClient { <span style="color: rgba(0, 0, 255, 1)">get</span>; <span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">; }

      </span><span style="color: rgba(0, 0, 255, 1)">public</span> IMongoDatabase DatabaseName { <span style="color: rgba(0, 0, 255, 1)">get</span>; <span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">; }

      </span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> MongoConnection(IConfiguration configuration)
      {
            MongoDBClient </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> MongoClient(configuration[<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">MongoSettings:Connection</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">]);
            DatabaseName </span>= MongoDBClient.GetDatabase(configuration[<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">MongoSettings:DatabaseName</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">]);
      }
    }</span></pre>
</div>
<h2>定义Mongo DBContext上下文</h2>
<blockquote>
<p>现在我们将定义MongoDB DBContext上下文类,具体到一个业务对象或需要被持久化的对象,这个上下文类将封装数据库的连接和集合。<br>该类应负责建立与所需数据库的连接,在建立连接后,该类将在内存中或按请求持有数据库上下文(基于API管道中配置的生命周期管理。)</p>
























</blockquote>
<h3>定义IMongoContext接口&nbsp;</h3>
<div class="cnblogs_code">
<pre>    <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">interface</span><span style="color: rgba(0, 0, 0, 1)"> IMongoContext : IDisposable
    {
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 添加命令操作
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="func"&gt;</span><span style="color: rgba(0, 128, 0, 1)">委托 方法接受一个 Func</span><span style="color: rgba(128, 128, 128, 1)">&lt;IClientSessionHandle, Task&gt;</span><span style="color: rgba(0, 128, 0, 1)"> 委托作为参数,该委托表示一个需要 IClientSessionHandle 对象作为参数并返回一个异步任务的方法</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      Task AddCommandAsync(Func&lt;IClientSessionHandle, Task&gt;<span style="color: rgba(0, 0, 0, 1)"> func);

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 提交更改并返回受影响的行数
      </span><span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> TODO:MongoDB单机服务器不支持事务【使用MongoDB事务会报错:Standalone servers do not support transactions】,只有在集群情况下才支持事务
      </span><span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 原因:MongoDB在使用分布式事务时需要进行多节点之间的协调和通信,而单机环境下无法实现这样的分布式协调和通信机制。但是,在MongoDB部署为一个集群(cluster)后,将多个计算机连接为一个整体,通过协调和通信机制实现了分布式事务的正常使用。从数据一致性和可靠性的角度来看,在分布式系统中实现事务处理是至关重要的。而在单机环境下不支持事务,只有在集群情况下才支持事务的设计方式是为了保证数据一致性和可靠性,并且也符合分布式系统的设计思想。
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="session"&gt;</span><span style="color: rgba(0, 128, 0, 1)">MongoDB 会话(session)对象</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      Task&lt;<span style="color: rgba(0, 0, 255, 1)">int</span>&gt;<span style="color: rgba(0, 0, 0, 1)"> SaveChangesAsync(IClientSessionHandle session);

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 初始化Mongodb会话对象session
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      Task&lt;IClientSessionHandle&gt;<span style="color: rgba(0, 0, 0, 1)"> StartSessionAsync();

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 获取集合数据
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;typeparam name="T"&gt;&lt;/typeparam&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="name"&gt;&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      IMongoCollection&lt;T&gt; GetCollection&lt;T&gt;(<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> name);
    }</span></pre>
</div>
<h3>定义MongoContext类</h3>
<div class="cnblogs_code">
<pre>    <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> MongoContext : IMongoContext
    {
      </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span><span style="color: rgba(0, 0, 0, 1)"> IMongoDatabase _databaseName;
      </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span><span style="color: rgba(0, 0, 0, 1)"> MongoClient _mongoClient;
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">这里将 _commands 中的每个元素都定义为一个 Func&lt;IClientSessionHandle, Task&gt; 委托,此委托表示一个需要 IClientSessionHandle 对象作为参数并返回一个异步任务的方法
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">每个委托都表示一个MongoDB 会话(session)对象和要执行的命令</span>
      <span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span> List&lt;Func&lt;IClientSessionHandle, Task&gt;&gt; _commands = <span style="color: rgba(0, 0, 255, 1)">new</span> List&lt;Func&lt;IClientSessionHandle, Task&gt;&gt;<span style="color: rgba(0, 0, 0, 1)">();

      </span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> MongoContext(IMongoConnection mongoConnection)
      {
            _mongoClient </span>=<span style="color: rgba(0, 0, 0, 1)"> mongoConnection.MongoDBClient;
            _databaseName </span>=<span style="color: rgba(0, 0, 0, 1)"> mongoConnection.DatabaseName;
      }

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 添加命令操作
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="func"&gt;</span><span style="color: rgba(0, 128, 0, 1)">方法接受一个 Func</span><span style="color: rgba(128, 128, 128, 1)">&lt;IClientSessionHandle, Task&gt;</span><span style="color: rgba(0, 128, 0, 1)"> 委托作为参数,该委托表示一个需要 IClientSessionHandle 对象作为参数并返回一个异步任务的方法</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task AddCommandAsync(Func&lt;IClientSessionHandle, Task&gt;<span style="color: rgba(0, 0, 0, 1)"> func)
      {
            _commands.Add(func);
            </span><span style="color: rgba(0, 0, 255, 1)">await</span><span style="color: rgba(0, 0, 0, 1)"> Task.CompletedTask;
      }

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 提交更改并返回受影响的行数
      </span><span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> TODO:MongoDB单机服务器不支持事务【使用MongoDB事务会报错:Standalone servers do not support transactions】,只有在集群情况下才支持事务
      </span><span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 原因:MongoDB在使用分布式事务时需要进行多节点之间的协调和通信,而单机环境下无法实现这样的分布式协调和通信机制。但是,在MongoDB部署为一个集群(cluster)后,将多个计算机连接为一个整体,通过协调和通信机制实现了分布式事务的正常使用。从数据一致性和可靠性的角度来看,在分布式系统中实现事务处理是至关重要的。而在单机环境下不支持事务,只有在集群情况下才支持事务的设计方式是为了保证数据一致性和可靠性,并且也符合分布式系统的设计思想。
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="session"&gt;</span><span style="color: rgba(0, 128, 0, 1)">MongoDB 会话(session)对象</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task&lt;<span style="color: rgba(0, 0, 255, 1)">int</span>&gt;<span style="color: rgba(0, 0, 0, 1)"> SaveChangesAsync(IClientSessionHandle session)
      {
            </span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">
            {
                session.StartTransaction();</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">开始事务</span>

                <span style="color: rgba(0, 0, 255, 1)">foreach</span> (<span style="color: rgba(0, 0, 255, 1)">var</span> command <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> _commands)
                {
                  </span><span style="color: rgba(0, 0, 255, 1)">await</span><span style="color: rgba(0, 0, 0, 1)"> command(session);
                  </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">语句实现了对事务中所有操作的异步执行,并等待它们完成。如果没有错误发生,程序会继续执行session.CommitTransactionAsync();方法,将之前进行的所有更改一起提交到MongoDB服务器上,从而实现事务提交。</span>
<span style="color: rgba(0, 0, 0, 1)">                }

                </span><span style="color: rgba(0, 0, 255, 1)">await</span> session.CommitTransactionAsync();<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">提交事务</span>
                <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> _commands.Count;
            }
            </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception ex)
            {
                </span><span style="color: rgba(0, 0, 255, 1)">await</span> session.AbortTransactionAsync();<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">回滚事务</span>
                <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
            }
            </span><span style="color: rgba(0, 0, 255, 1)">finally</span><span style="color: rgba(0, 0, 0, 1)">
            {
                _commands.Clear();</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">清空_commands列表中的元素</span>
<span style="color: rgba(0, 0, 0, 1)">            }
      }

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 初始化Mongodb会话对象session
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task&lt;IClientSessionHandle&gt;<span style="color: rgba(0, 0, 0, 1)"> StartSessionAsync()
      {
            </span><span style="color: rgba(0, 0, 255, 1)">var</span> session = <span style="color: rgba(0, 0, 255, 1)">await</span><span style="color: rgba(0, 0, 0, 1)"> _mongoClient.StartSessionAsync();
            </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> session;
      }

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 获取MongoDB集合
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;typeparam name="T"&gt;&lt;/typeparam&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="name"&gt;</span><span style="color: rgba(0, 128, 0, 1)">集合名称</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> IMongoCollection&lt;T&gt; GetCollection&lt;T&gt;(<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> name)
      {
            </span><span style="color: rgba(0, 0, 255, 1)">return</span> _databaseName.GetCollection&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)">(name);
      }

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 释放上下文
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> Dispose()
      {
            GC.SuppressFinalize(</span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">);
      }
    }</span></pre>
</div>
<h2>定义通用泛型Repository</h2>
<blockquote>
<p>Repository(仓储)是DDD(领域驱动设计)中的经典思想,可以归纳为介于实际业务层(领域层)和数据访问层之间的层,能让领域层能在感觉不到数据访问层的情况下,完成与数据库的交互和以往的DAO(数据访问)层相比,Repository层的设计理念更偏向于面向对象,而淡化直接对数据表进行的CRUD操作。</p>
</blockquote>
<h3>定义IMongoRepository接口</h3>
<blockquote>
<p>定义一个泛型Repository通用接口,抽象常用的增加,删除,修改,查询等操作方法。</p>
</blockquote>
<div class="cnblogs_code">
<pre>    <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">interface</span> IMongoRepository&lt;T&gt; <span style="color: rgba(0, 0, 255, 1)">where</span> T : <span style="color: rgba(0, 0, 255, 1)">class</span>, <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)">()
    {
      </span><span style="color: rgba(0, 0, 255, 1)">#region</span> 事务操作示例

      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 事务添加数据
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="session"&gt;</span><span style="color: rgba(0, 128, 0, 1)">MongoDB 会话(session)对象</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="objData"&gt;</span><span style="color: rgba(0, 128, 0, 1)">添加数据</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
<span style="color: rgba(0, 0, 0, 1)">      Task AddTransactionsAsync(IClientSessionHandle session, T objData);

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 事务数据删除
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="session"&gt;</span><span style="color: rgba(0, 128, 0, 1)">MongoDB 会话(session)对象</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="id"&gt;</span><span style="color: rgba(0, 128, 0, 1)">objectId</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      Task DeleteTransactionsAsync(IClientSessionHandle session, <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> id);

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 事务异步局部更新(仅更新一条记录)
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="session"&gt;</span><span style="color: rgba(0, 128, 0, 1)">MongoDB 会话(session)对象</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="filter"&gt;</span><span style="color: rgba(0, 128, 0, 1)">过滤器</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="update"&gt;</span><span style="color: rgba(0, 128, 0, 1)">更新条件</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      Task UpdateTransactionsAsync(IClientSessionHandle session, FilterDefinition&lt;T&gt; filter, UpdateDefinition&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)"> update);

      </span><span style="color: rgba(0, 0, 255, 1)">#endregion</span>

      <span style="color: rgba(0, 0, 255, 1)">#region</span> 添加相关操作

      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 添加数据
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="objData"&gt;</span><span style="color: rgba(0, 128, 0, 1)">添加数据</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
<span style="color: rgba(0, 0, 0, 1)">      Task AddAsync(T objData);

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 批量插入
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="objDatas"&gt;</span><span style="color: rgba(0, 128, 0, 1)">实体集合</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      Task InsertManyAsync(List&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)"> objDatas);

      </span><span style="color: rgba(0, 0, 255, 1)">#endregion</span>

      <span style="color: rgba(0, 0, 255, 1)">#region</span> 删除相关操作

      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 数据删除
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="id"&gt;</span><span style="color: rgba(0, 128, 0, 1)">objectId</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      Task DeleteAsync(<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> id);

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 异步删除多条数据
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="filter"&gt;</span><span style="color: rgba(0, 128, 0, 1)">删除的条件</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      Task&lt;DeleteResult&gt; DeleteManyAsync(FilterDefinition&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)"> filter);

      </span><span style="color: rgba(0, 0, 255, 1)">#endregion</span>

      <span style="color: rgba(0, 0, 255, 1)">#region</span> 修改相关操作

      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 指定对象异步修改一条数据
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="obj"&gt;</span><span style="color: rgba(0, 128, 0, 1)">要修改的对象</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="id"&gt;</span><span style="color: rgba(0, 128, 0, 1)">修改条件</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      Task UpdateAsync(T obj, <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> id);

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 局部更新(仅更新一条记录)
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;para&gt;&lt;!]&gt;</span><span style="color: rgba(128, 128, 128, 1)">&lt;/para&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;para&gt;&lt;!]&gt;</span><span style="color: rgba(128, 128, 128, 1)">&lt;/para&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="expression"&gt;</span><span style="color: rgba(0, 128, 0, 1)">筛选条件</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="entity"&gt;</span><span style="color: rgba(0, 128, 0, 1)">更新条件</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      Task UpdateAsync(Expression&lt;Func&lt;T, <span style="color: rgba(0, 0, 255, 1)">bool</span>&gt;&gt; expression, Expression&lt;Action&lt;T&gt;&gt;<span style="color: rgba(0, 0, 0, 1)"> entity);

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 异步局部更新(仅更新一条记录)
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="filter"&gt;</span><span style="color: rgba(0, 128, 0, 1)">过滤器</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="update"&gt;</span><span style="color: rgba(0, 128, 0, 1)">更新条件</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      Task UpdateAsync(FilterDefinition&lt;T&gt; filter, UpdateDefinition&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)"> update);

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 异步局部更新(仅更新多条记录)
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="expression"&gt;</span><span style="color: rgba(0, 128, 0, 1)">筛选条件</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="update"&gt;</span><span style="color: rgba(0, 128, 0, 1)">更新条件</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      Task UpdateManyAsync(Expression&lt;Func&lt;T, <span style="color: rgba(0, 0, 255, 1)">bool</span>&gt;&gt; expression, UpdateDefinition&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)"> update);

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 异步批量修改数据
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="dic"&gt;</span><span style="color: rgba(0, 128, 0, 1)">要修改的字段</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="filter"&gt;</span><span style="color: rgba(0, 128, 0, 1)">更新条件</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      Task&lt;UpdateResult&gt; UpdateManayAsync(Dictionary&lt;<span style="color: rgba(0, 0, 255, 1)">string</span>, <span style="color: rgba(0, 0, 255, 1)">string</span>&gt; dic, FilterDefinition&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)"> filter);

      </span><span style="color: rgba(0, 0, 255, 1)">#endregion</span>

      <span style="color: rgba(0, 0, 255, 1)">#region</span> 查询统计相关操作

      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 通过ID主键获取数据
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="id"&gt;</span><span style="color: rgba(0, 128, 0, 1)">objectId</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      Task&lt;T&gt; GetByIdAsync(<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> id);
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 获取所有数据
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      Task&lt;IEnumerable&lt;T&gt;&gt;<span style="color: rgba(0, 0, 0, 1)"> GetAllAsync();

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 获取记录数
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="expression"&gt;</span><span style="color: rgba(0, 128, 0, 1)">筛选条件</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      Task&lt;<span style="color: rgba(0, 0, 255, 1)">long</span>&gt; CountAsync(Expression&lt;Func&lt;T, <span style="color: rgba(0, 0, 255, 1)">bool</span>&gt;&gt;<span style="color: rgba(0, 0, 0, 1)"> expression);

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 获取记录数
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="filter"&gt;</span><span style="color: rgba(0, 128, 0, 1)">过滤器</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      Task&lt;<span style="color: rgba(0, 0, 255, 1)">long</span>&gt; CountAsync(FilterDefinition&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)"> filter);

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 判断是否存在
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="predicate"&gt;</span><span style="color: rgba(0, 128, 0, 1)">条件</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      Task&lt;<span style="color: rgba(0, 0, 255, 1)">bool</span>&gt; ExistsAsync(Expression&lt;Func&lt;T, <span style="color: rgba(0, 0, 255, 1)">bool</span>&gt;&gt;<span style="color: rgba(0, 0, 0, 1)"> predicate);

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 异步查询集合
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="filter"&gt;</span><span style="color: rgba(0, 128, 0, 1)">查询条件</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="field"&gt;</span><span style="color: rgba(0, 128, 0, 1)">要查询的字段,不写时查询全部</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="sort"&gt;</span><span style="color: rgba(0, 128, 0, 1)">要排序的字段</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      Task&lt;List&lt;T&gt;&gt; FindListAsync(FilterDefinition&lt;T&gt; filter, <span style="color: rgba(0, 0, 255, 1)">string</span>[]? field = <span style="color: rgba(0, 0, 255, 1)">null</span>, SortDefinition&lt;T&gt;? sort = <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">);

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 异步分页查询集合
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="filter"&gt;</span><span style="color: rgba(0, 128, 0, 1)">查询条件</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="pageIndex"&gt;</span><span style="color: rgba(0, 128, 0, 1)">当前页</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="pageSize"&gt;</span><span style="color: rgba(0, 128, 0, 1)">页容量</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="field"&gt;</span><span style="color: rgba(0, 128, 0, 1)">要查询的字段,不写时查询全部</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="sort"&gt;</span><span style="color: rgba(0, 128, 0, 1)">要排序的字段</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      Task&lt;List&lt;T&gt;&gt; FindListByPageAsync(FilterDefinition&lt;T&gt; filter, <span style="color: rgba(0, 0, 255, 1)">int</span> pageIndex, <span style="color: rgba(0, 0, 255, 1)">int</span> pageSize, <span style="color: rgba(0, 0, 255, 1)">string</span>[]? field = <span style="color: rgba(0, 0, 255, 1)">null</span>, SortDefinition&lt;T&gt;? sort = <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">);

      </span><span style="color: rgba(0, 0, 255, 1)">#endregion</span><span style="color: rgba(0, 0, 0, 1)">
    }</span></pre>
</div>
<h3>实现泛型MongoBaseRepository基类</h3>
<div class="cnblogs_code">
<pre>    <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span> MongoBaseRepository&lt;T&gt; : IMongoRepository&lt;T&gt; <span style="color: rgba(0, 0, 255, 1)">where</span> T : <span style="color: rgba(0, 0, 255, 1)">class</span>, <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)">()
    {
      </span><span style="color: rgba(0, 0, 255, 1)">protected</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span><span style="color: rgba(0, 0, 0, 1)"> IMongoContext _context;
      </span><span style="color: rgba(0, 0, 255, 1)">protected</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span> IMongoCollection&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)"> _dbSet;
      </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span> <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> _collectionName;

      </span><span style="color: rgba(0, 0, 255, 1)">protected</span><span style="color: rgba(0, 0, 0, 1)"> MongoBaseRepository(IMongoContext context)
      {
            _context </span>=<span style="color: rgba(0, 0, 0, 1)"> context;
            _collectionName </span>= <span style="color: rgba(0, 0, 255, 1)">typeof</span>(T).GetAttributeValue((TableAttribute m) =&gt; m.Name) ?? <span style="color: rgba(0, 0, 255, 1)">typeof</span><span style="color: rgba(0, 0, 0, 1)">(T).Name;
            _dbSet </span>= _context.GetCollection&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)">(_collectionName);
      }

      </span><span style="color: rgba(0, 0, 255, 1)">#region</span> 事务操作示例

      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 事务添加数据
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="session"&gt;</span><span style="color: rgba(0, 128, 0, 1)">MongoDB 会话(session)对象</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="objData"&gt;</span><span style="color: rgba(0, 128, 0, 1)">添加数据</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">async</span><span style="color: rgba(0, 0, 0, 1)"> Task AddTransactionsAsync(IClientSessionHandle session, T objData)
      {
            </span><span style="color: rgba(0, 0, 255, 1)">await</span> _context.AddCommandAsync(<span style="color: rgba(0, 0, 255, 1)">async</span> (session) =&gt; <span style="color: rgba(0, 0, 255, 1)">await</span><span style="color: rgba(0, 0, 0, 1)"> _dbSet.InsertOneAsync(objData));
      }

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 事务数据删除
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="session"&gt;</span><span style="color: rgba(0, 128, 0, 1)">MongoDB 会话(session)对象</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="id"&gt;</span><span style="color: rgba(0, 128, 0, 1)">objectId</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task DeleteTransactionsAsync(IClientSessionHandle session, <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> id)
      {
            </span><span style="color: rgba(0, 0, 255, 1)">await</span> _context.AddCommandAsync((session) =&gt; _dbSet.DeleteOneAsync(Builders&lt;T&gt;.Filter.Eq(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)"> _id </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, id)));
      }

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 事务异步局部更新(仅更新一条记录)
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="session"&gt;</span><span style="color: rgba(0, 128, 0, 1)">MongoDB 会话(session)对象</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="filter"&gt;</span><span style="color: rgba(0, 128, 0, 1)">过滤器</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="update"&gt;</span><span style="color: rgba(0, 128, 0, 1)">更新条件</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task UpdateTransactionsAsync(IClientSessionHandle session, FilterDefinition&lt;T&gt; filter, UpdateDefinition&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)"> update)
      {
            </span><span style="color: rgba(0, 0, 255, 1)">await</span> _context.AddCommandAsync((session) =&gt;<span style="color: rgba(0, 0, 0, 1)"> _dbSet.UpdateOneAsync(filter, update));
      }

      </span><span style="color: rgba(0, 0, 255, 1)">#endregion</span>

      <span style="color: rgba(0, 0, 255, 1)">#region</span> 添加相关操作

      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 添加数据
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="objData"&gt;</span><span style="color: rgba(0, 128, 0, 1)">添加数据</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">async</span><span style="color: rgba(0, 0, 0, 1)"> Task AddAsync(T objData)
      {
            </span><span style="color: rgba(0, 0, 255, 1)">await</span><span style="color: rgba(0, 0, 0, 1)"> _dbSet.InsertOneAsync(objData);
      }

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 批量插入
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="objDatas"&gt;</span><span style="color: rgba(0, 128, 0, 1)">实体集合</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task InsertManyAsync(List&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)"> objDatas)
      {
            </span><span style="color: rgba(0, 0, 255, 1)">await</span><span style="color: rgba(0, 0, 0, 1)"> _dbSet.InsertManyAsync(objDatas);
      }

      </span><span style="color: rgba(0, 0, 255, 1)">#endregion</span>

      <span style="color: rgba(0, 0, 255, 1)">#region</span> 删除相关操作

      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 数据删除
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="id"&gt;</span><span style="color: rgba(0, 128, 0, 1)">objectId</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task DeleteAsync(<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> id)
      {
            </span><span style="color: rgba(0, 0, 255, 1)">await</span> _dbSet.DeleteOneAsync(Builders&lt;T&gt;.Filter.Eq(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">_id</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ObjectId(id)));
      }

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 异步删除多条数据
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="filter"&gt;</span><span style="color: rgba(0, 128, 0, 1)">删除的条件</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task&lt;DeleteResult&gt; DeleteManyAsync(FilterDefinition&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)"> filter)
      {
            </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">await</span><span style="color: rgba(0, 0, 0, 1)"> _dbSet.DeleteManyAsync(filter);
      }

      </span><span style="color: rgba(0, 0, 255, 1)">#endregion</span>

      <span style="color: rgba(0, 0, 255, 1)">#region</span> 修改相关操作

      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 指定对象异步修改一条数据
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="obj"&gt;</span><span style="color: rgba(0, 128, 0, 1)">要修改的对象</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="id"&gt;</span><span style="color: rgba(0, 128, 0, 1)">修改条件</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task UpdateAsync(T obj, <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> id)
      {
            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">修改条件</span>
            FilterDefinition&lt;T&gt; filter = Builders&lt;T&gt;.Filter.Eq(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">_id</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ObjectId(id));
            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">要修改的字段</span>
            <span style="color: rgba(0, 0, 255, 1)">var</span> list = <span style="color: rgba(0, 0, 255, 1)">new</span> List&lt;UpdateDefinition&lt;T&gt;&gt;<span style="color: rgba(0, 0, 0, 1)">();
            </span><span style="color: rgba(0, 0, 255, 1)">foreach</span> (<span style="color: rgba(0, 0, 255, 1)">var</span> item <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> obj.GetType().GetProperties())
            {
                </span><span style="color: rgba(0, 0, 255, 1)">if</span> (item.Name.ToLower() == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">id</span><span style="color: rgba(128, 0, 0, 1)">"</span>) <span style="color: rgba(0, 0, 255, 1)">continue</span><span style="color: rgba(0, 0, 0, 1)">;
                list.Add(Builders</span>&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)">.Update.Set(item.Name, item.GetValue(obj)));
            }
            </span><span style="color: rgba(0, 0, 255, 1)">var</span> updatefilter = Builders&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)">.Update.Combine(list);
            </span><span style="color: rgba(0, 0, 255, 1)">await</span><span style="color: rgba(0, 0, 0, 1)"> _dbSet.UpdateOneAsync(filter, updatefilter);
      }

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 局部更新(仅更新一条记录)
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;para&gt;&lt;!]&gt;</span><span style="color: rgba(128, 128, 128, 1)">&lt;/para&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;para&gt;&lt;!]&gt;</span><span style="color: rgba(128, 128, 128, 1)">&lt;/para&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="expression"&gt;</span><span style="color: rgba(0, 128, 0, 1)">筛选条件</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="entity"&gt;</span><span style="color: rgba(0, 128, 0, 1)">更新条件</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task UpdateAsync(Expression&lt;Func&lt;T, <span style="color: rgba(0, 0, 255, 1)">bool</span>&gt;&gt; expression, Expression&lt;Action&lt;T&gt;&gt;<span style="color: rgba(0, 0, 0, 1)"> entity)
      {
            </span><span style="color: rgba(0, 0, 255, 1)">var</span> fieldList = <span style="color: rgba(0, 0, 255, 1)">new</span> List&lt;UpdateDefinition&lt;T&gt;&gt;<span style="color: rgba(0, 0, 0, 1)">();

            </span><span style="color: rgba(0, 0, 255, 1)">if</span> (entity.Body <span style="color: rgba(0, 0, 255, 1)">is</span><span style="color: rgba(0, 0, 0, 1)"> MemberInitExpression param)
            {
                </span><span style="color: rgba(0, 0, 255, 1)">foreach</span> (<span style="color: rgba(0, 0, 255, 1)">var</span> item <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> param.Bindings)
                {
                  </span><span style="color: rgba(0, 0, 255, 1)">var</span> propertyName =<span style="color: rgba(0, 0, 0, 1)"> item.Member.Name;
                  </span><span style="color: rgba(0, 0, 255, 1)">object</span> propertyValue = <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;

                  </span><span style="color: rgba(0, 0, 255, 1)">if</span> (item <span style="color: rgba(0, 0, 255, 1)">is</span> not MemberAssignment memberAssignment) <span style="color: rgba(0, 0, 255, 1)">continue</span><span style="color: rgba(0, 0, 0, 1)">;

                  </span><span style="color: rgba(0, 0, 255, 1)">if</span> (memberAssignment.Expression.NodeType ==<span style="color: rgba(0, 0, 0, 1)"> ExpressionType.Constant)
                  {
                        </span><span style="color: rgba(0, 0, 255, 1)">if</span> (memberAssignment.Expression <span style="color: rgba(0, 0, 255, 1)">is</span><span style="color: rgba(0, 0, 0, 1)"> ConstantExpression constantExpression)
                            propertyValue </span>=<span style="color: rgba(0, 0, 0, 1)"> constantExpression.Value;
                  }
                  </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
                  {
                        propertyValue </span>= Expression.Lambda(memberAssignment.Expression, <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">).Compile().DynamicInvoke();
                  }

                  </span><span style="color: rgba(0, 0, 255, 1)">if</span> (propertyName != <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">_id</span><span style="color: rgba(128, 0, 0, 1)">"</span>) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">实体键_id不允许更新</span>
<span style="color: rgba(0, 0, 0, 1)">                  {
                        fieldList.Add(Builders</span>&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)">.Update.Set(propertyName, propertyValue));
                  }
                }
            }

            </span><span style="color: rgba(0, 0, 255, 1)">await</span> _dbSet.UpdateOneAsync(expression, Builders&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)">.Update.Combine(fieldList));
      }

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 异步局部更新(仅更新一条记录)
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="filter"&gt;</span><span style="color: rgba(0, 128, 0, 1)">过滤器</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="update"&gt;</span><span style="color: rgba(0, 128, 0, 1)">更新条件</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task UpdateAsync(FilterDefinition&lt;T&gt; filter, UpdateDefinition&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)"> update)
      {
            </span><span style="color: rgba(0, 0, 255, 1)">await</span><span style="color: rgba(0, 0, 0, 1)"> _dbSet.UpdateOneAsync(filter, update);
      }

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 异步局部更新(仅更新多条记录)
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="expression"&gt;</span><span style="color: rgba(0, 128, 0, 1)">筛选条件</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="update"&gt;</span><span style="color: rgba(0, 128, 0, 1)">更新条件</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task UpdateManyAsync(Expression&lt;Func&lt;T, <span style="color: rgba(0, 0, 255, 1)">bool</span>&gt;&gt; expression, UpdateDefinition&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)"> update)
      {
            </span><span style="color: rgba(0, 0, 255, 1)">await</span><span style="color: rgba(0, 0, 0, 1)"> _dbSet.UpdateManyAsync(expression, update);
      }

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 异步批量修改数据
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="dic"&gt;</span><span style="color: rgba(0, 128, 0, 1)">要修改的字段</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="filter"&gt;</span><span style="color: rgba(0, 128, 0, 1)">更新条件</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task&lt;UpdateResult&gt; UpdateManayAsync(Dictionary&lt;<span style="color: rgba(0, 0, 255, 1)">string</span>, <span style="color: rgba(0, 0, 255, 1)">string</span>&gt; dic, FilterDefinition&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)"> filter)
      {
            T t </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> T();
            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">要修改的字段</span>
            <span style="color: rgba(0, 0, 255, 1)">var</span> list = <span style="color: rgba(0, 0, 255, 1)">new</span> List&lt;UpdateDefinition&lt;T&gt;&gt;<span style="color: rgba(0, 0, 0, 1)">();
            </span><span style="color: rgba(0, 0, 255, 1)">foreach</span> (<span style="color: rgba(0, 0, 255, 1)">var</span> item <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> t.GetType().GetProperties())
            {
                </span><span style="color: rgba(0, 0, 255, 1)">if</span> (!dic.ContainsKey(item.Name)) <span style="color: rgba(0, 0, 255, 1)">continue</span><span style="color: rgba(0, 0, 0, 1)">;
                </span><span style="color: rgba(0, 0, 255, 1)">var</span> value =<span style="color: rgba(0, 0, 0, 1)"> dic;
                list.Add(Builders</span>&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)">.Update.Set(item.Name, value));
            }
            </span><span style="color: rgba(0, 0, 255, 1)">var</span> updatefilter = Builders&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)">.Update.Combine(list);
            </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">await</span><span style="color: rgba(0, 0, 0, 1)"> _dbSet.UpdateManyAsync(filter, updatefilter);
      }

      </span><span style="color: rgba(0, 0, 255, 1)">#endregion</span>

      <span style="color: rgba(0, 0, 255, 1)">#region</span> 查询统计相关操作

      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 通过ID主键获取数据
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="id"&gt;</span><span style="color: rgba(0, 128, 0, 1)">objectId</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task&lt;T&gt; GetByIdAsync(<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> id)
      {
            </span><span style="color: rgba(0, 0, 255, 1)">var</span> queryData = <span style="color: rgba(0, 0, 255, 1)">await</span> _dbSet.FindAsync(Builders&lt;T&gt;.Filter.Eq(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">_id</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ObjectId(id)));
            </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> queryData.FirstOrDefault();
      }

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 获取所有数据
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task&lt;IEnumerable&lt;T&gt;&gt;<span style="color: rgba(0, 0, 0, 1)"> GetAllAsync()
      {
            </span><span style="color: rgba(0, 0, 255, 1)">var</span> queryAllData = <span style="color: rgba(0, 0, 255, 1)">await</span> _dbSet.FindAsync(Builders&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)">.Filter.Empty);
            </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> queryAllData.ToList();
      }

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 获取记录数
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="expression"&gt;</span><span style="color: rgba(0, 128, 0, 1)">筛选条件</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task&lt;<span style="color: rgba(0, 0, 255, 1)">long</span>&gt; CountAsync(Expression&lt;Func&lt;T, <span style="color: rgba(0, 0, 255, 1)">bool</span>&gt;&gt;<span style="color: rgba(0, 0, 0, 1)"> expression)
      {
            </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">await</span><span style="color: rgba(0, 0, 0, 1)"> _dbSet.CountDocumentsAsync(expression);
      }

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 获取记录数
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="filter"&gt;</span><span style="color: rgba(0, 128, 0, 1)">过滤器</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task&lt;<span style="color: rgba(0, 0, 255, 1)">long</span>&gt; CountAsync(FilterDefinition&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)"> filter)
      {
            </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">await</span><span style="color: rgba(0, 0, 0, 1)"> _dbSet.CountDocumentsAsync(filter);
      }

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 判断是否存在
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="predicate"&gt;</span><span style="color: rgba(0, 128, 0, 1)">条件</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task&lt;<span style="color: rgba(0, 0, 255, 1)">bool</span>&gt; ExistsAsync(Expression&lt;Func&lt;T, <span style="color: rgba(0, 0, 255, 1)">bool</span>&gt;&gt;<span style="color: rgba(0, 0, 0, 1)"> predicate)
      {
            </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">await</span><span style="color: rgba(0, 0, 0, 1)"> Task.FromResult(_dbSet.AsQueryable().Any(predicate));
      }

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 异步查询集合
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="filter"&gt;</span><span style="color: rgba(0, 128, 0, 1)">查询条件</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="field"&gt;</span><span style="color: rgba(0, 128, 0, 1)">要查询的字段,不写时查询全部</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="sort"&gt;</span><span style="color: rgba(0, 128, 0, 1)">要排序的字段</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task&lt;List&lt;T&gt;&gt; FindListAsync(FilterDefinition&lt;T&gt; filter, <span style="color: rgba(0, 0, 255, 1)">string</span>[]? field = <span style="color: rgba(0, 0, 255, 1)">null</span>, SortDefinition&lt;T&gt;? sort = <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
      {
            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">不指定查询字段</span>
            <span style="color: rgba(0, 0, 255, 1)">if</span> (field == <span style="color: rgba(0, 0, 255, 1)">null</span> || field.Length == <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
            {
                </span><span style="color: rgba(0, 0, 255, 1)">if</span> (sort == <span style="color: rgba(0, 0, 255, 1)">null</span>) <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">await</span><span style="color: rgba(0, 0, 0, 1)"> _dbSet.Find(filter).ToListAsync();
                </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">await</span><span style="color: rgba(0, 0, 0, 1)"> _dbSet.Find(filter).Sort(sort).ToListAsync();
            }

            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">指定查询字段</span>
            <span style="color: rgba(0, 0, 255, 1)">var</span> fieldList = <span style="color: rgba(0, 0, 255, 1)">new</span> List&lt;ProjectionDefinition&lt;T&gt;&gt;<span style="color: rgba(0, 0, 0, 1)">();
            </span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = <span style="color: rgba(128, 0, 128, 1)">0</span>; i &lt; field.Length; i++<span style="color: rgba(0, 0, 0, 1)">)
            {
                fieldList.Add(Builders</span>&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)">.Projection.Include(field.ToString()));
            }
            </span><span style="color: rgba(0, 0, 255, 1)">var</span> projection = Builders&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)">.Projection.Combine(fieldList);
            fieldList</span>?<span style="color: rgba(0, 0, 0, 1)">.Clear();

            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">不排序</span>
            <span style="color: rgba(0, 0, 255, 1)">if</span> (sort == <span style="color: rgba(0, 0, 255, 1)">null</span>) <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">await</span> _dbSet.Find(filter).Project&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)">(projection).ToListAsync();

            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">排序查询</span>
            <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">await</span> _dbSet.Find(filter).Sort(sort).Project&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)">(projection).ToListAsync();
      }

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 异步分页查询集合
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="filter"&gt;</span><span style="color: rgba(0, 128, 0, 1)">查询条件</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="pageIndex"&gt;</span><span style="color: rgba(0, 128, 0, 1)">当前页</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="pageSize"&gt;</span><span style="color: rgba(0, 128, 0, 1)">页容量</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="field"&gt;</span><span style="color: rgba(0, 128, 0, 1)">要查询的字段,不写时查询全部</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="sort"&gt;</span><span style="color: rgba(0, 128, 0, 1)">要排序的字段</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task&lt;List&lt;T&gt;&gt; FindListByPageAsync(FilterDefinition&lt;T&gt; filter, <span style="color: rgba(0, 0, 255, 1)">int</span> pageIndex, <span style="color: rgba(0, 0, 255, 1)">int</span> pageSize, <span style="color: rgba(0, 0, 255, 1)">string</span>[]? field = <span style="color: rgba(0, 0, 255, 1)">null</span>, SortDefinition&lt;T&gt;? sort = <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
      {
            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">不指定查询字段</span>
            <span style="color: rgba(0, 0, 255, 1)">if</span> (field == <span style="color: rgba(0, 0, 255, 1)">null</span> || field.Length == <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
            {
                </span><span style="color: rgba(0, 0, 255, 1)">if</span> (sort == <span style="color: rgba(0, 0, 255, 1)">null</span>) <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">await</span> _dbSet.Find(filter).Skip((pageIndex - <span style="color: rgba(128, 0, 128, 1)">1</span>) *<span style="color: rgba(0, 0, 0, 1)"> pageSize).Limit(pageSize).ToListAsync();
                </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">进行排序</span>
                <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">await</span> _dbSet.Find(filter).Sort(sort).Skip((pageIndex - <span style="color: rgba(128, 0, 128, 1)">1</span>) *<span style="color: rgba(0, 0, 0, 1)"> pageSize).Limit(pageSize).ToListAsync();
            }

            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">指定查询字段</span>
            <span style="color: rgba(0, 0, 255, 1)">var</span> fieldList = <span style="color: rgba(0, 0, 255, 1)">new</span> List&lt;ProjectionDefinition&lt;T&gt;&gt;<span style="color: rgba(0, 0, 0, 1)">();
            </span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = <span style="color: rgba(128, 0, 128, 1)">0</span>; i &lt; field.Length; i++<span style="color: rgba(0, 0, 0, 1)">)
            {
                fieldList.Add(Builders</span>&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)">.Projection.Include(field.ToString()));
            }
            </span><span style="color: rgba(0, 0, 255, 1)">var</span> projection = Builders&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)">.Projection.Combine(fieldList);
            fieldList</span>?<span style="color: rgba(0, 0, 0, 1)">.Clear();

            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">不排序</span>
            <span style="color: rgba(0, 0, 255, 1)">if</span> (sort == <span style="color: rgba(0, 0, 255, 1)">null</span>) <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">await</span> _dbSet.Find(filter).Project&lt;T&gt;(projection).Skip((pageIndex - <span style="color: rgba(128, 0, 128, 1)">1</span>) *<span style="color: rgba(0, 0, 0, 1)"> pageSize).Limit(pageSize).ToListAsync();

            </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">排序查询</span>
            <span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">await</span> _dbSet.Find(filter).Sort(sort).Project&lt;T&gt;(projection).Skip((pageIndex - <span style="color: rgba(128, 0, 128, 1)">1</span>) *<span style="color: rgba(0, 0, 0, 1)"> pageSize).Limit(pageSize).ToListAsync();
      }

      </span><span style="color: rgba(0, 0, 255, 1)">#endregion</span><span style="color: rgba(0, 0, 0, 1)">
    }</span></pre>
</div>
<h2 id="工作单元模式">工作单元模式</h2>
<blockquote>
<p>工作单元模式是“维护一个被业务事务影响的对象列表,协调变化的写入和并发问题的解决”。具体来说,在C#工作单元模式中,我们通过UnitOfWork对象来管理多个Repository对象,同时UnitOfWork还提供了对事务的支持。对于一组需要用到多个Repository的业务操作,我们可以在UnitOfWork中创建一个事务,并将多个Repository操作放在同一个事务中处理,以保证数据的一致性。当所有Repository操作完成后,再通过UnitOfWork提交事务或者回滚事务。</p>
</blockquote>
<h3 id="一定义iunitofwork接口">定义IUnitOfWork接口</h3>
<div class="cnblogs_code">
<pre>    <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
    <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 工作单元接口
    </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">interface</span><span style="color: rgba(0, 0, 0, 1)"> IUnitOfWork : IDisposable
    {
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 提交保存更改
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="session"&gt;</span><span style="color: rgba(0, 128, 0, 1)">MongoDB 会话(session)对象</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      Task&lt;<span style="color: rgba(0, 0, 255, 1)">bool</span>&gt;<span style="color: rgba(0, 0, 0, 1)"> Commit(IClientSessionHandle session);

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 初始化MongoDB会话对象session
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      Task&lt;IClientSessionHandle&gt;<span style="color: rgba(0, 0, 0, 1)"> InitTransaction();
    }</span></pre>
</div>
<h3 id="二定义unitofwork类">定义UnitOfWork类</h3>
<div class="cnblogs_code">
<pre>    <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
    <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 工作单元类
    </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> UnitOfWork : IUnitOfWork
    {
      </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span><span style="color: rgba(0, 0, 0, 1)"> IMongoContext _context;

      </span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> UnitOfWork(IMongoContext context)
      {
            _context </span>=<span style="color: rgba(0, 0, 0, 1)"> context;
      }

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 提交保存更改
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;param name="session"&gt;</span><span style="color: rgba(0, 128, 0, 1)">MongoDB 会话(session)对象</span><span style="color: rgba(128, 128, 128, 1)">&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task&lt;<span style="color: rgba(0, 0, 255, 1)">bool</span>&gt;<span style="color: rgba(0, 0, 0, 1)"> Commit(IClientSessionHandle session)
      {
            </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">await</span> _context.SaveChangesAsync(session) &gt; <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
      }

      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 初始化MongoDB会话对象session
      </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;returns&gt;&lt;/returns&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task&lt;IClientSessionHandle&gt;<span style="color: rgba(0, 0, 0, 1)"> InitTransaction()
      {
            </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">await</span><span style="color: rgba(0, 0, 0, 1)"> _context.StartSessionAsync();
      }

      </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> Dispose()
      {
            _context.Dispose();
      }
    }</span></pre>
</div>
<h2>注册数据库基础操作和工作单元</h2>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">注册数据库基础操作和工作单元</span>
builder.Services.AddSingleton&lt;IMongoConnection, MongoConnection&gt;<span style="color: rgba(0, 0, 0, 1)">();
builder.Services.AddScoped</span>&lt;IMongoContext, MongoContext&gt;<span style="color: rgba(0, 0, 0, 1)">();
builder.Services.AddScoped</span>&lt;IUnitOfWork, UnitOfWork&gt;<span style="color: rgba(0, 0, 0, 1)">();
builder.Services.AddScoped</span>&lt;IUserRepository, UserRepository&gt;();</pre>
</div>
<h2>参考文章</h2>
<p>NoSQL – MongoDB Repository Implementation in .NET Core with Unit Testing example</p>
<p>ASP.NET CORE – MONGODB REPOSITORY PATTERN &amp; UNIT OF WORK</p>

</div>
<div id="MySignature" role="contentinfo">
    <blockquote >
<p style='font-family:YouYuan;font-size: 16px;margin: 0 auto 0.01em auto;'><span style='font-size: 17px; '>作者名称:</span>追逐时光者</p>
<p style='font-family:YouYuan;font-size: 16px;margin: 0 auto 0.01em auto;'><span style='font-size: 17px; '>作者简介:</span>一个热爱编程、善于分享、喜欢学习、探索、尝试新事物和新技术的全栈软件工程师。</p>
<p style='font-family:YouYuan;font-size: 16px;margin: 0 auto 0.01em auto;'>
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。如果该篇文章对您有帮助的话,可以点一下右下角的【&hearts;推荐&hearts;】,希望能够持续的为大家带来好的技术文章,文中可能存在描述不正确的地方,欢迎指正或补充,不胜感激。
</p>
</blockquote><br><br>
来源:https://www.cnblogs.com/Can-daydayup/p/17157135.html
頁: [1]
查看完整版本: .NET Core MongoDB数据仓储和工作单元模式封装