基于C#的MongoDB数据库开发应用(3)--MongoDB数据库的C#开发之异步接口
<p>在前面的系列博客中,我曾经介绍过,MongoDB数据库的C#驱动已经全面支持异步的处理接口,并且接口的定义几乎是重写了。本篇主要介绍MongoDB数据库的C#驱动的最新接口使用,介绍基于新接口如何实现基础的增删改查及分页等处理,以及如何利用异步接口实现基类相关的异步操作。</p><p>MongoDB数据库驱动在2.2版本(或者是从2.0开始)好像完全改写了API的接口,因此目前这个版本同时支持两个版本的API处理,一个是基于MongoDatabase的对象接口,一个是IMongoDatabase的对象接口,前者中规中矩,和我们使用Shell里面的命令名称差不多,后者IMongoDatabase的接口是基于异步的,基本上和前者差别很大,而且接口都提供了异步的处理操作。</p>
<h3>1、MongoDB数据库C#驱动的新接口</h3>
<p>新接口也还是基于数据库,集合,文档这样的处理概念进行封装,只是它们的接口不再一样了,我们还是按照前面的做法,定义一个数据库访问的基类,对MongoDB数据库的相关操作封装在基类里面,方便使用,同时基类利用泛型对象,实现更强类型的约束及支持,如基类BaseDAL的定义如下所示。</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">partial</span> <span style="color: rgba(0, 0, 255, 1)">class</span> BaseDAL<T> <span style="color: rgba(0, 0, 255, 1)">where</span> T : BaseEntity, <span style="color: rgba(0, 0, 255, 1)">new</span>()</pre>
</div>
<p>利用泛型的方式,把数据访问层的接口提出来,并引入了数据访问层的基类进行实现和重用接口,如下所示。</p>
<p><img src="https://images2015.cnblogs.com/blog/8867/201601/8867-20160106191000934-243118883.png" alt="" width="401" height="322"></p>
<p><img src="https://images2015.cnblogs.com/blog/8867/201601/8867-20160106191819387-865077769.png" alt=""></p>
<p><span style="line-height: 1.5">基于新接口,如获取数据库对象的操作,则利用了</span><span style="line-height: 1.5">IMongoDatabase的接口了,如下所示。</span></p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(0, 0, 255, 1)">var</span> client = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> MongoClient(connectionString);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> database = client.GetDatabase(<span style="color: rgba(0, 0, 255, 1)">new</span> MongoUrl(connectionString).DatabaseName);</pre>
</div>
<p>相对以前的常规接口,MongoClient对象已经没有了<strong>GetServer</strong>的接口了。如果对创建数据库对象的操作做更好的封装,可以利用配置文件进行指定的话,那么方法可以封装如下所示。</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 根据数据库配置信息创建MongoDatabase对象,如果不指定配置信息,则从默认信息创建
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="databaseName"></span><span style="color: rgba(0, 128, 0, 1)">数据库名称,默认空为local</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 0, 255, 1)">protected</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span><span style="color: rgba(0, 0, 0, 1)"> IMongoDatabase CreateDatabase()
{
</span><span style="color: rgba(0, 0, 255, 1)">string</span> connectionString = <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> (!<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">.IsNullOrEmpty(dbConfigName))
{
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">从配置文件中获取对应的连接信息</span>
connectionString =<span style="color: rgba(0, 0, 0, 1)"> ConfigurationManager.ConnectionStrings.ConnectionString;
}
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
{
connectionString </span>=<span style="color: rgba(0, 0, 0, 1)"> defaultConnectionString;
}
</span><span style="color: rgba(0, 0, 255, 1)">var</span> client = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> MongoClient(connectionString);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> database = client.GetDatabase(<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> MongoUrl(connectionString).DatabaseName);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> database;
}</span></pre>
</div>
<p>根据IMongoDatabase 接口,那么其获取集合对象的操作如下所示,它使用了另外一个定义IMongoCollection了。</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 获取操作对象的IMongoCollection集合,强类型对象集合
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> IMongoCollection<T><span style="color: rgba(0, 0, 0, 1)"> GetCollection()
{
</span><span style="color: rgba(0, 0, 255, 1)">var</span> database =<span style="color: rgba(0, 0, 0, 1)"> CreateDatabase();
</span><span style="color: rgba(0, 0, 255, 1)">return</span> database.GetCollection<T>(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.entitysName);
}</span></pre>
</div>
<h3>2、查询单个对象实现封装处理</h3>
<p>基于新接口的查询处理,已经没有FindOne的方法定义了,只是使用了Find的方法,而且也没有了Query的对象可以作为条件进行处理,而是采用了新的定义对象FilterDefinition,例如对于根据ID查询单个对象,接口的实现如下所示。</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="key"></span><span style="color: rgba(0, 128, 0, 1)">对象的ID值</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></span><span style="color: rgba(0, 128, 0, 1)">存在则返回指定的对象,否则返回Null</span><span style="color: rgba(128, 128, 128, 1)"></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> T FindByID(<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> id)
{
ArgumentValidation.CheckForEmptyString(id, </span><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)">);
IMongoCollection</span><T> collection =<span style="color: rgba(0, 0, 0, 1)"> GetCollection();
</span><span style="color: rgba(0, 0, 255, 1)">return</span> collection.Find(s=> s.Id ==<span style="color: rgba(0, 0, 0, 1)"> id).FirstOrDefault();
}</span></pre>
</div>
<p>对于利用FilterDefinition进行查询的操作,如下所示。</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="filter"></span><span style="color: rgba(0, 128, 0, 1)">条件表达式</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></span><span style="color: rgba(0, 128, 0, 1)">存在则返回指定的第一个对象,否则返回默认值</span><span style="color: rgba(128, 128, 128, 1)"></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> T FindSingle(FilterDefinition<T><span style="color: rgba(0, 0, 0, 1)"> filter)
{
IMongoCollection</span><T> collection =<span style="color: rgba(0, 0, 0, 1)"> GetCollection();
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> collection.Find(filter).FirstOrDefault();
} </span></pre>
</div>
<p>我们可以看到,这些都是利用Find方法的不同重载实现不同条件的处理的。</p>
<p>对于这个新接口,异步是一个重要的改变,那么它的异步处理是如何的呢,我们看看上面两个异步的实现操作,具体代码如下所示。</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="key"></span><span style="color: rgba(0, 128, 0, 1)">对象的ID值</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></span><span style="color: rgba(0, 128, 0, 1)">存在则返回指定的对象,否则返回Null</span><span style="color: rgba(128, 128, 128, 1)"></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task<T> FindByIDAsync(<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> id)
{
ArgumentValidation.CheckForEmptyString(id, </span><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)">);
IMongoCollection</span><T> collection =<span style="color: rgba(0, 0, 0, 1)"> GetCollection();
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">await</span> collection.<strong><span style="color: rgba(255, 0, 0, 1)">FindAsync</span></strong>(s=>s.Id ==<span style="color: rgba(0, 0, 0, 1)"> id).Result.FirstOrDefaultAsync();
}
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="query"></span><span style="color: rgba(0, 128, 0, 1)">条件表达式</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></span><span style="color: rgba(0, 128, 0, 1)">存在则返回指定的第一个对象,否则返回默认值</span><span style="color: rgba(128, 128, 128, 1)"></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task<T> FindSingleAsync(FilterDefinition<T><span style="color: rgba(0, 0, 0, 1)"> query)
{
</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)"> GetQueryable(query).<strong><span style="color: rgba(255, 0, 0, 1)">SingleOrDefaultAsync</span></strong>();
}</span></pre>
</div>
<p>我们看到,上面的Collection或者GetQueryable(query)返回的对象,都提供给了以Async结尾的异步方法,因此对异步的封装也是非常方便的,上面的<span style="line-height: 16.8px">GetQueryable(query)是另外一个公共的实现方法,具体代码如下所示。</span></p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="query"></span><span style="color: rgba(0, 128, 0, 1)">查询条件</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> IFindFluent<T, T> GetQueryable(FilterDefinition<T><span style="color: rgba(0, 0, 0, 1)"> query)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> GetQueryable(query, <span style="color: rgba(0, 0, 255, 1)">this</span>.SortPropertyName, <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.IsDescending);
}</span></pre>
</div>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="query"></span><span style="color: rgba(0, 128, 0, 1)">查询条件</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="sortPropertyName"></span><span style="color: rgba(0, 128, 0, 1)">排序表达式</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="isDescending"></span><span style="color: rgba(0, 128, 0, 1)">如果为true则为降序,否则为升序</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> IFindFluent<T,T> GetQueryable(FilterDefinition<T> query, <span style="color: rgba(0, 0, 255, 1)">string</span> sortPropertyName, <span style="color: rgba(0, 0, 255, 1)">bool</span> isDescending = <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">)
{
IMongoCollection</span><T> collection =<span style="color: rgba(0, 0, 0, 1)"> GetCollection();
IFindFluent</span><T, T> queryable =<span style="color: rgba(0, 0, 0, 1)"> collection.Find(query);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> sort = <span style="color: rgba(0, 0, 255, 1)">this</span>.IsDescending ? Builders<T>.Sort.Descending(<span style="color: rgba(0, 0, 255, 1)">this</span>.SortPropertyName) : Builders<T>.Sort.Ascending(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.SortPropertyName);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> queryable.Sort(sort);
}</span></pre>
</div>
<p><span style="line-height: 1.5">我们可以看到,它返回了</span><span style="line-height: 1.5">IFindFluent<T, T>的对象,这个和以前返回的IMongoQuery对象又有不同,基本上,使用最新的接口,所有的实现都不太一样,这也是因为MongoDB还在不停变化之中有关。</span></p>
<h3><span style="line-height: 1.5">3、GetQueryable几种方式</span></h3>
<p>为了简化代码,方便使用,我们对获取MongoDB的LINQ方式的处理做了简单的封装,提供了几个GetQueryable的方式,具体代码如下所示。</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> IQueryable<T><span style="color: rgba(0, 0, 0, 1)"> GetQueryable()
{
IMongoCollection</span><T> collection =<span style="color: rgba(0, 0, 0, 1)"> GetCollection();
IQueryable</span><T> query =<span style="color: rgba(0, 0, 0, 1)"> collection.AsQueryable();
</span><span style="color: rgba(0, 0, 255, 1)">return</span> query.OrderBy(<span style="color: rgba(0, 0, 255, 1)">this</span>.SortPropertyName, <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.IsDescending);
}</span></pre>
</div>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="match"></span><span style="color: rgba(0, 128, 0, 1)">查询条件</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="orderByProperty"></span><span style="color: rgba(0, 128, 0, 1)">排序表达式</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="isDescending"></span><span style="color: rgba(0, 128, 0, 1)">如果为true则为降序,否则为升序</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> IQueryable<T> GetQueryable<TKey>(Expression<Func<T, <span style="color: rgba(0, 0, 255, 1)">bool</span>>> match, Expression<Func<T, TKey>> orderByProperty, <span style="color: rgba(0, 0, 255, 1)">bool</span> isDescending = <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">)
{
IMongoCollection</span><T> collection =<span style="color: rgba(0, 0, 0, 1)"> GetCollection();
IQueryable</span><T> query =<span style="color: rgba(0, 0, 0, 1)"> collection.AsQueryable();
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (match != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
{
query </span>=<span style="color: rgba(0, 0, 0, 1)"> query.Where(match);
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (orderByProperty != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
{
query </span>= isDescending ?<span style="color: rgba(0, 0, 0, 1)"> query.OrderByDescending(orderByProperty) : query.OrderBy(orderByProperty);
}
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
{
query </span>= query.OrderBy(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.SortPropertyName, isDescending);
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> query;
}</span></pre>
</div>
<p>以及基于FilterDefinition的条件处理,并返回IFindFluent<T,T>接口对象的代码如下所示。</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="query"></span><span style="color: rgba(0, 128, 0, 1)">查询条件</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="sortPropertyName"></span><span style="color: rgba(0, 128, 0, 1)">排序表达式</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="isDescending"></span><span style="color: rgba(0, 128, 0, 1)">如果为true则为降序,否则为升序</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> IFindFluent<T,T> GetQueryable(FilterDefinition<T> query, <span style="color: rgba(0, 0, 255, 1)">string</span> sortPropertyName, <span style="color: rgba(0, 0, 255, 1)">bool</span> isDescending = <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">)
{
IMongoCollection</span><T> collection =<span style="color: rgba(0, 0, 0, 1)"> GetCollection();
IFindFluent</span><T, T> queryable =<span style="color: rgba(0, 0, 0, 1)"> collection.Find(query);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> sort = <span style="color: rgba(0, 0, 255, 1)">this</span>.IsDescending ? Builders<T>.Sort.Descending(<span style="color: rgba(0, 0, 255, 1)">this</span>.SortPropertyName) : Builders<T>.Sort.Ascending(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.SortPropertyName);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> queryable.Sort(sort);
}</span></pre>
</div>
<h3>4、集合的查询操作封装处理</h3>
<p>基于上面的封装,对结合的查询,也是基于不同的条件进行处理,返回对应的列表的处理方式, 最简单的是利用GetQueryable方式进行处理,代码如下所示。</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="match"></span><span style="color: rgba(0, 128, 0, 1)">条件表达式</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></span><span style="color: rgba(0, 128, 0, 1)">指定对象的集合</span><span style="color: rgba(128, 128, 128, 1)"></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> IList<T> Find(Expression<Func<T, <span style="color: rgba(0, 0, 255, 1)">bool</span>>><span style="color: rgba(0, 0, 0, 1)"> match)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> GetQueryable(match).ToList();
}</span></pre>
</div>
<p>或者如下所示</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="match"></span><span style="color: rgba(0, 128, 0, 1)">条件表达式</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></span><span style="color: rgba(0, 128, 0, 1)">指定对象的集合</span><span style="color: rgba(128, 128, 128, 1)"></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> IList<T> Find(FilterDefinition<T><span style="color: rgba(0, 0, 0, 1)"> query)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> GetQueryable(query).ToList();
}</span></pre>
</div>
<p>以及对排序字段,以及升降序的处理操作如下所示。</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="match"></span><span style="color: rgba(0, 128, 0, 1)">条件表达式</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="orderByProperty"></span><span style="color: rgba(0, 128, 0, 1)">排序表达式</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="isDescending"></span><span style="color: rgba(0, 128, 0, 1)">如果为true则为降序,否则为升序</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> IList<T> Find<TKey>(Expression<Func<T, <span style="color: rgba(0, 0, 255, 1)">bool</span>>> match, Expression<Func<T, TKey>> orderByProperty, <span style="color: rgba(0, 0, 255, 1)">bool</span> isDescending = <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> GetQueryable<TKey><span style="color: rgba(0, 0, 0, 1)">(match, orderByProperty, isDescending).ToList();
}
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="query"></span><span style="color: rgba(0, 128, 0, 1)">条件表达式</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="orderByProperty"></span><span style="color: rgba(0, 128, 0, 1)">排序字段</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="isDescending"></span><span style="color: rgba(0, 128, 0, 1)">如果为true则为降序,否则为升序</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> IList<T> Find<TKey>(FilterDefinition<T> query, <span style="color: rgba(0, 0, 255, 1)">string</span> orderByProperty, <span style="color: rgba(0, 0, 255, 1)">bool</span> isDescending = <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> GetQueryable(query, orderByProperty, isDescending).ToList();
}</span></pre>
</div>
<p>以及利用这些条件进行分页的处理代码如下所示。</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="match"></span><span style="color: rgba(0, 128, 0, 1)">条件表达式</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="info"></span><span style="color: rgba(0, 128, 0, 1)">分页实体</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></span><span style="color: rgba(0, 128, 0, 1)">指定对象的集合</span><span style="color: rgba(128, 128, 128, 1)"></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> IList<T> FindWithPager(<span style="color: rgba(255, 0, 0, 1)">Expression</span><Func<T, <span style="color: rgba(0, 0, 255, 1)">bool</span>>><span style="color: rgba(0, 0, 0, 1)"> match, PagerInfo info)
{
</span><span style="color: rgba(0, 0, 255, 1)">int</span> pageindex = (info.CurrenetPageIndex < <span style="color: rgba(128, 0, 128, 1)">1</span>) ? <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)"> : info.CurrenetPageIndex;
</span><span style="color: rgba(0, 0, 255, 1)">int</span> pageSize = (info.PageSize <= <span style="color: rgba(128, 0, 128, 1)">0</span>) ? <span style="color: rgba(128, 0, 128, 1)">20</span><span style="color: rgba(0, 0, 0, 1)"> : info.PageSize;
</span><span style="color: rgba(0, 0, 255, 1)">int</span> excludedRows = (pageindex - <span style="color: rgba(128, 0, 128, 1)">1</span>) *<span style="color: rgba(0, 0, 0, 1)"> pageSize;
IQueryable</span><T> query =<span style="color: rgba(0, 0, 0, 1)"> GetQueryable(match);
info.RecordCount </span>=<span style="color: rgba(0, 0, 0, 1)"> query.Count();
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"><strong><span style="color: rgba(255, 0, 0, 1)"> query.Skip(excludedRows).Take(pageSize).ToList();</span></strong>
}
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="query"></span><span style="color: rgba(0, 128, 0, 1)">条件表达式</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="info"></span><span style="color: rgba(0, 128, 0, 1)">分页实体</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></span><span style="color: rgba(0, 128, 0, 1)">指定对象的集合</span><span style="color: rgba(128, 128, 128, 1)"></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> IList<T> FindWithPager(<span style="color: rgba(255, 0, 0, 1)">FilterDefinition</span><T><span style="color: rgba(0, 0, 0, 1)"> query, PagerInfo info)
{
</span><span style="color: rgba(0, 0, 255, 1)">int</span> pageindex = (info.CurrenetPageIndex < <span style="color: rgba(128, 0, 128, 1)">1</span>) ? <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)"> : info.CurrenetPageIndex;
</span><span style="color: rgba(0, 0, 255, 1)">int</span> pageSize = (info.PageSize <= <span style="color: rgba(128, 0, 128, 1)">0</span>) ? <span style="color: rgba(128, 0, 128, 1)">20</span><span style="color: rgba(0, 0, 0, 1)"> : info.PageSize;
</span><span style="color: rgba(0, 0, 255, 1)">int</span> excludedRows = (pageindex - <span style="color: rgba(128, 0, 128, 1)">1</span>) *<span style="color: rgba(0, 0, 0, 1)"> pageSize;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> find =<span style="color: rgba(0, 0, 0, 1)"> GetQueryable(query);
info.RecordCount </span>= (<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">)find.Count();
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"><strong><span style="color: rgba(255, 0, 0, 1)"> find.Skip(excludedRows).Limit(pageSize).ToList();</span></strong>
}</span></pre>
</div>
<p>对于异步的封装处理,基本上也和上面的操作差不多,例如对于基础的查询,异步操作封装如下所示。</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="match"></span><span style="color: rgba(0, 128, 0, 1)">条件表达式</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></span><span style="color: rgba(0, 128, 0, 1)">指定对象的集合</span><span style="color: rgba(128, 128, 128, 1)"></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task<IList<T>> FindAsync(<span style="color: rgba(255, 0, 0, 1)">Expression</span><Func<T, <span style="color: rgba(0, 0, 255, 1)">bool</span>>><span style="color: rgba(0, 0, 0, 1)"> match)
{
</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(GetQueryable(match).ToList());
}
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="query"></span><span style="color: rgba(0, 128, 0, 1)">条件表达式</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></span><span style="color: rgba(0, 128, 0, 1)">指定对象的集合</span><span style="color: rgba(128, 128, 128, 1)"></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task<IList<T>> FindAsync(<span style="color: rgba(255, 0, 0, 1)">FilterDefinition</span><T><span style="color: rgba(0, 0, 0, 1)"> query)
{
</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)"> GetQueryable(query).ToListAsync();
}</span></pre>
</div>
<p>复杂一点的分页处理操作代码封装如下所示。</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="match"></span><span style="color: rgba(0, 128, 0, 1)">条件表达式</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="info"></span><span style="color: rgba(0, 128, 0, 1)">分页实体</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></span><span style="color: rgba(0, 128, 0, 1)">指定对象的集合</span><span style="color: rgba(128, 128, 128, 1)"></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task<IList<T>> FindWithPagerAsync(Expression<Func<T, <span style="color: rgba(0, 0, 255, 1)">bool</span>>><span style="color: rgba(0, 0, 0, 1)"> match, PagerInfo info)
{
</span><span style="color: rgba(0, 0, 255, 1)">int</span> pageindex = (info.CurrenetPageIndex < <span style="color: rgba(128, 0, 128, 1)">1</span>) ? <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)"> : info.CurrenetPageIndex;
</span><span style="color: rgba(0, 0, 255, 1)">int</span> pageSize = (info.PageSize <= <span style="color: rgba(128, 0, 128, 1)">0</span>) ? <span style="color: rgba(128, 0, 128, 1)">20</span><span style="color: rgba(0, 0, 0, 1)"> : info.PageSize;
</span><span style="color: rgba(0, 0, 255, 1)">int</span> excludedRows = (pageindex - <span style="color: rgba(128, 0, 128, 1)">1</span>) *<span style="color: rgba(0, 0, 0, 1)"> pageSize;
IQueryable</span><T> query =<span style="color: rgba(0, 0, 0, 1)"> GetQueryable(match);
info.RecordCount </span>=<span style="color: rgba(0, 0, 0, 1)"> query.Count();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> result =<span style="color: rgba(0, 0, 0, 1)"> query.Skip(excludedRows).Take(pageSize).ToList();
</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(result);
}
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="query"></span><span style="color: rgba(0, 128, 0, 1)">条件表达式</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="info"></span><span style="color: rgba(0, 128, 0, 1)">分页实体</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></span><span style="color: rgba(0, 128, 0, 1)">指定对象的集合</span><span style="color: rgba(128, 128, 128, 1)"></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task<IList<T>> FindWithPagerAsync(FilterDefinition<T><span style="color: rgba(0, 0, 0, 1)"> query, PagerInfo info)
{
</span><span style="color: rgba(0, 0, 255, 1)">int</span> pageindex = (info.CurrenetPageIndex < <span style="color: rgba(128, 0, 128, 1)">1</span>) ? <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)"> : info.CurrenetPageIndex;
</span><span style="color: rgba(0, 0, 255, 1)">int</span> pageSize = (info.PageSize <= <span style="color: rgba(128, 0, 128, 1)">0</span>) ? <span style="color: rgba(128, 0, 128, 1)">20</span><span style="color: rgba(0, 0, 0, 1)"> : info.PageSize;
</span><span style="color: rgba(0, 0, 255, 1)">int</span> excludedRows = (pageindex - <span style="color: rgba(128, 0, 128, 1)">1</span>) *<span style="color: rgba(0, 0, 0, 1)"> pageSize;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> queryable =<span style="color: rgba(0, 0, 0, 1)"> GetQueryable(query);
info.RecordCount </span>= (<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">)queryable.Count();
</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)"> queryable.Skip(excludedRows).Limit(pageSize).ToListAsync();
}</span></pre>
</div>
<h3>5、增删改方法封装处理</h3>
<p>对于常规的增删改操作,在新的MongoDB数据库驱动里面也修改了名称,使用的时候也需要进行调整处理了。</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="t"></span><span style="color: rgba(0, 128, 0, 1)">指定的对象</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> Insert(T t)
{
ArgumentValidation.CheckForNullReference(t, </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">传入的对象t为空</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
IMongoCollection</span><T> collection =<span style="color: rgba(0, 0, 0, 1)"> GetCollection();
collection.InsertOne(t);
}</span></pre>
</div>
<p>异步的操作实现如下所示。</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="t"></span><span style="color: rgba(0, 128, 0, 1)">指定的对象</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">async</span><span style="color: rgba(0, 0, 0, 1)"> Task InsertAsync(T t)
{
ArgumentValidation.CheckForNullReference(t, </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">传入的对象t为空</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
IMongoCollection</span><T> collection =<span style="color: rgba(0, 0, 0, 1)"> GetCollection();
</span><span style="color: rgba(0, 0, 255, 1)">await</span><span style="color: rgba(0, 0, 0, 1)"> collection.<span style="color: rgba(255, 0, 0, 1)">InsertOneAsync</span>(t);
}</span></pre>
</div>
<p>批量插入记录的操作如下所示。</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="list"></span><span style="color: rgba(0, 128, 0, 1)">指定的对象集合</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">void</span> InsertBatch(IEnumerable<T><span style="color: rgba(0, 0, 0, 1)"> list)
{
ArgumentValidation.CheckForNullReference(list, </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">传入的对象list为空</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
IMongoCollection</span><T> collection =<span style="color: rgba(0, 0, 0, 1)"> GetCollection();
collection.<span style="color: rgba(255, 0, 0, 1)">InsertMany</span>(list);
}</span></pre>
</div>
<p>对应的异步操作处理如下所示,这些都是利用原生支持的异步处理接口实现的。</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="list"></span><span style="color: rgba(0, 128, 0, 1)">指定的对象集合</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task InsertBatchAsync(IEnumerable<T><span style="color: rgba(0, 0, 0, 1)"> list)
{
ArgumentValidation.CheckForNullReference(list, </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">传入的对象list为空</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
IMongoCollection</span><T> collection =<span style="color: rgba(0, 0, 0, 1)"> GetCollection();
</span><span style="color: rgba(0, 0, 255, 1)">await</span><span style="color: rgba(0, 0, 0, 1)"> collection.<span style="color: rgba(255, 0, 0, 1)">InsertManyAsync</span>(list);
}</span></pre>
</div>
<p>更新操作,有一种整个替换更新,还有一个是部分更新,它们两者是有区别的,如对于替换更新的操作,它的接口封装处理如下所示</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="t"></span><span style="color: rgba(0, 128, 0, 1)">指定的对象</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="id"></span><span style="color: rgba(0, 128, 0, 1)">主键的值</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></span><span style="color: rgba(0, 128, 0, 1)">执行成功返回</span><span style="color: rgba(128, 128, 128, 1)"><c></span><span style="color: rgba(0, 128, 0, 1)">true</span><span style="color: rgba(128, 128, 128, 1)"></c></span><span style="color: rgba(0, 128, 0, 1)">,否则为</span><span style="color: rgba(128, 128, 128, 1)"><c></span><span style="color: rgba(0, 128, 0, 1)">false</span><span style="color: rgba(128, 128, 128, 1)"></c></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> Update(T t, <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> id)
{
ArgumentValidation.CheckForNullReference(t, </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">传入的对象t为空</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
ArgumentValidation.CheckForEmptyString(id, </span><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)">);
</span><span style="color: rgba(0, 0, 255, 1)">bool</span> result = <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
IMongoCollection</span><T> collection =<span style="color: rgba(0, 0, 0, 1)"> GetCollection();
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">使用 IsUpsert = true ,如果没有记录则写入</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> update = collection.<span style="color: rgba(255, 0, 0, 1)"><strong>ReplaceOne</strong></span>(s => s.Id == id, t, <span style="color: rgba(0, 0, 255, 1)">new</span> UpdateOptions() { <span style="color: rgba(255, 0, 0, 1)">IsUpsert</span> = <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)"> });
result </span>= update != <span style="color: rgba(0, 0, 255, 1)">null</span> && update.ModifiedCount > <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)">return</span><span style="color: rgba(0, 0, 0, 1)"> result;
}</span></pre>
</div>
<p>如果对于部分字段的更新,那么操作如下所示 ,主要是利用UpdateDefinition对象来指定需要更新那些字段属性及值等信息。</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="id"></span><span style="color: rgba(0, 128, 0, 1)">主键的值</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="update"></span><span style="color: rgba(0, 128, 0, 1)">更新对象</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></span><span style="color: rgba(0, 128, 0, 1)">执行成功返回</span><span style="color: rgba(128, 128, 128, 1)"><c></span><span style="color: rgba(0, 128, 0, 1)">true</span><span style="color: rgba(128, 128, 128, 1)"></c></span><span style="color: rgba(0, 128, 0, 1)">,否则为</span><span style="color: rgba(128, 128, 128, 1)"><c></span><span style="color: rgba(0, 128, 0, 1)">false</span><span style="color: rgba(128, 128, 128, 1)"></c></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> Update(<span style="color: rgba(0, 0, 255, 1)">string</span> id, <strong><span style="color: rgba(255, 0, 0, 1)">UpdateDefinition</span></strong><T><span style="color: rgba(0, 0, 0, 1)"> update)
{
ArgumentValidation.CheckForNullReference(update, </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">传入的对象update为空</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
ArgumentValidation.CheckForEmptyString(id, </span><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)">);
IMongoCollection</span><T> collection =<span style="color: rgba(0, 0, 0, 1)"> GetCollection();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> result = collection.<strong><span style="color: rgba(255, 0, 0, 1)">UpdateOne</span></strong>(s => s.Id == id, update, <span style="color: rgba(0, 0, 255, 1)">new</span> UpdateOptions() { IsUpsert = <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)"> });
</span><span style="color: rgba(0, 0, 255, 1)">return</span> result != <span style="color: rgba(0, 0, 255, 1)">null</span> && result.ModifiedCount > <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
}</span></pre>
</div>
<p>上面的异步更新操作如下所示。</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="id"></span><span style="color: rgba(0, 128, 0, 1)">主键的值</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="update"></span><span style="color: rgba(0, 128, 0, 1)">更新对象</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></span><span style="color: rgba(0, 128, 0, 1)">执行成功返回</span><span style="color: rgba(128, 128, 128, 1)"><c></span><span style="color: rgba(0, 128, 0, 1)">true</span><span style="color: rgba(128, 128, 128, 1)"></c></span><span style="color: rgba(0, 128, 0, 1)">,否则为</span><span style="color: rgba(128, 128, 128, 1)"><c></span><span style="color: rgba(0, 128, 0, 1)">false</span><span style="color: rgba(128, 128, 128, 1)"></c></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task<<span style="color: rgba(0, 0, 255, 1)">bool</span>> UpdateAsync(<span style="color: rgba(0, 0, 255, 1)">string</span> id, UpdateDefinition<T><span style="color: rgba(0, 0, 0, 1)"> update)
{
ArgumentValidation.CheckForNullReference(update, </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">传入的对象update为空</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
ArgumentValidation.CheckForEmptyString(id, </span><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)">);
IMongoCollection</span><T> collection =<span style="color: rgba(0, 0, 0, 1)"> GetCollection();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> result = <span style="color: rgba(0, 0, 255, 1)">await</span> collection.UpdateOneAsync(s => s.Id == id, update, <span style="color: rgba(0, 0, 255, 1)">new</span> UpdateOptions() { IsUpsert = <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)"> });
</span><span style="color: rgba(0, 0, 255, 1)">var</span> sucess = result != <span style="color: rgba(0, 0, 255, 1)">null</span> && result.ModifiedCount > <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)">return</span> <span style="color: rgba(0, 0, 255, 1)">await</span><span style="color: rgba(0, 0, 0, 1)"> Task.FromResult(sucess);
}</span></pre>
</div>
<p>删除的操作也是类似的了,基本上和上面的处理方式接近,顺便列出来供参考学习。</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="id"></span><span style="color: rgba(0, 128, 0, 1)">对象的ID</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></span><span style="color: rgba(0, 128, 0, 1)">执行成功返回</span><span style="color: rgba(128, 128, 128, 1)"><c></span><span style="color: rgba(0, 128, 0, 1)">true</span><span style="color: rgba(128, 128, 128, 1)"></c></span><span style="color: rgba(0, 128, 0, 1)">,否则为</span><span style="color: rgba(128, 128, 128, 1)"><c></span><span style="color: rgba(0, 128, 0, 1)">false</span><span style="color: rgba(128, 128, 128, 1)"></c></span><span style="color: rgba(0, 128, 0, 1)">。</span><span style="color: rgba(128, 128, 128, 1)"></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> Delete(<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> id)
{
ArgumentValidation.CheckForEmptyString(id, </span><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)">);
IMongoCollection</span><T> collection =<span style="color: rgba(0, 0, 0, 1)"> GetCollection();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> result = collection.DeleteOne(s=> s.Id ==<span style="color: rgba(0, 0, 0, 1)"> id);
</span><span style="color: rgba(0, 0, 255, 1)">return</span> result != <span style="color: rgba(0, 0, 255, 1)">null</span> && result.DeletedCount > <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)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="idList"></span><span style="color: rgba(0, 128, 0, 1)">对象的ID集合</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></span><span style="color: rgba(0, 128, 0, 1)">执行成功返回</span><span style="color: rgba(128, 128, 128, 1)"><c></span><span style="color: rgba(0, 128, 0, 1)">true</span><span style="color: rgba(128, 128, 128, 1)"></c></span><span style="color: rgba(0, 128, 0, 1)">,否则为</span><span style="color: rgba(128, 128, 128, 1)"><c></span><span style="color: rgba(0, 128, 0, 1)">false</span><span style="color: rgba(128, 128, 128, 1)"></c></span><span style="color: rgba(0, 128, 0, 1)">。</span><span style="color: rgba(128, 128, 128, 1)"></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> DeleteBatch(List<<span style="color: rgba(0, 0, 255, 1)">string</span>><span style="color: rgba(0, 0, 0, 1)"> idList)
{
ArgumentValidation.CheckForNullReference(idList, </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">传入的对象idList为空</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
IMongoCollection</span><T> collection =<span style="color: rgba(0, 0, 0, 1)"> GetCollection();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> query = Query.In(<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)"> BsonArray(idList));
</span><span style="color: rgba(0, 0, 255, 1)">var</span> result = collection.DeleteMany(s =><span style="color: rgba(0, 0, 0, 1)"> idList.Contains(s.Id));
</span><span style="color: rgba(0, 0, 255, 1)">return</span> result != <span style="color: rgba(0, 0, 255, 1)">null</span> && result.DeletedCount > <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
}</span></pre>
</div>
<p>如果根据条件的删除,也可以利用条件定义的两种方式,具体代码如下所示。</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="match"></span><span style="color: rgba(0, 128, 0, 1)">条件表达式</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></span><span style="color: rgba(0, 128, 0, 1)">执行成功返回</span><span style="color: rgba(128, 128, 128, 1)"><c></span><span style="color: rgba(0, 128, 0, 1)">true</span><span style="color: rgba(128, 128, 128, 1)"></c></span><span style="color: rgba(0, 128, 0, 1)">,否则为</span><span style="color: rgba(128, 128, 128, 1)"><c></span><span style="color: rgba(0, 128, 0, 1)">false</span><span style="color: rgba(128, 128, 128, 1)"></c></span><span style="color: rgba(0, 128, 0, 1)">。</span><span style="color: rgba(128, 128, 128, 1)"></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> DeleteByExpression(Expression<Func<T, <span style="color: rgba(0, 0, 255, 1)">bool</span>>><span style="color: rgba(0, 0, 0, 1)"> match)
{
IMongoCollection</span><T> collection =<span style="color: rgba(0, 0, 0, 1)"> GetCollection();
collection.AsQueryable().Where(match).ToList().ForEach(s </span>=> collection.DeleteOne(t => t.Id ==<span style="color: rgba(0, 0, 0, 1)"> s.Id));
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">true</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)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="match"></span><span style="color: rgba(0, 128, 0, 1)">条件表达式</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></span><span style="color: rgba(0, 128, 0, 1)">执行成功返回</span><span style="color: rgba(128, 128, 128, 1)"><c></span><span style="color: rgba(0, 128, 0, 1)">true</span><span style="color: rgba(128, 128, 128, 1)"></c></span><span style="color: rgba(0, 128, 0, 1)">,否则为</span><span style="color: rgba(128, 128, 128, 1)"><c></span><span style="color: rgba(0, 128, 0, 1)">false</span><span style="color: rgba(128, 128, 128, 1)"></c></span><span style="color: rgba(0, 128, 0, 1)">。</span><span style="color: rgba(128, 128, 128, 1)"></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">virtual</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> DeleteByQuery(FilterDefinition<T><span style="color: rgba(0, 0, 0, 1)"> query)
{
IMongoCollection</span><T> collection =<span style="color: rgba(0, 0, 0, 1)"> GetCollection();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> result =<span style="color: rgba(0, 0, 0, 1)"> collection.DeleteMany(query);
</span><span style="color: rgba(0, 0, 255, 1)">return</span> result != <span style="color: rgba(0, 0, 255, 1)">null</span> && result.DeletedCount > <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
} </span></pre>
</div>
<h3>6、数据访问子类的封装和方法调用</h3>
<p>好了,基本上上面大多数使用的方法都发布出来了,封装的原则就是希望数据访问层子类能够简化代码,减少不必要的复制粘贴,而且必要的时候, 也可以对具体的接口进行重写,实现更强大的处理控制。</p>
<p>例如对于上面的基类,我们在具体的集合对象封装的时候,需要继承于BaseDAL<T>这样的方式,这样可以利用基类丰富的接口,简化子类的代码,如User集合类的代码如下所示。</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> User集合(表)的数据访问类
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span> User : BaseDAL<UserInfo><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)"><summary></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)"></summary></span>
<span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> User()
{
</span><span style="color: rgba(0, 0, 255, 1)">this</span>.entitysName = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">users</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)">对象在数据库的集合名称</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)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="id"></span><span style="color: rgba(0, 128, 0, 1)">记录ID</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="addAge"></span><span style="color: rgba(0, 128, 0, 1)">待增加的岁数</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> IncreaseAge(<span style="color: rgba(0, 0, 255, 1)">string</span> id, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> addAge)
{
</span><span style="color: rgba(0, 0, 255, 1)">var</span> collection =<span style="color: rgba(0, 0, 0, 1)"> GetCollection();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> update = Builders<UserInfo>.Update.Inc(s =><span style="color: rgba(0, 0, 0, 1)"> s.Age, addAge);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> result = collection.UpdateOne(s => s.Id ==<span style="color: rgba(0, 0, 0, 1)"> id, update);
</span><span style="color: rgba(0, 0, 255, 1)">return</span> result != <span style="color: rgba(0, 0, 255, 1)">null</span> && result.ModifiedCount > <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)"><summary></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)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="id"></span><span style="color: rgba(0, 128, 0, 1)">记录ID</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="newName"></span><span style="color: rgba(0, 128, 0, 1)">用户新名称</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> UpdateName(<span style="color: rgba(0, 0, 255, 1)">string</span> id, <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> newName)
{
</span><span style="color: rgba(0, 0, 255, 1)">var</span> collection =<span style="color: rgba(0, 0, 0, 1)"> GetCollection();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> update = Builders<UserInfo>.Update.Set(s =><span style="color: rgba(0, 0, 0, 1)"> s.Name, newName);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> result = collection.UpdateOne(s => s.Id ==<span style="color: rgba(0, 0, 0, 1)"> id, update);
</span><span style="color: rgba(0, 0, 255, 1)">return</span> result != <span style="color: rgba(0, 0, 255, 1)">null</span> && result.ModifiedCount > <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
}
}</span></pre>
</div>
<p>在界面层使用的时候,只需要声明一个对应的User数据访问类dal对象,就可以利用它的相关接口进行对应的数据操作了,如下代码所示。</p>
<div class="cnblogs_code">
<pre> IList<UserInfo> members = dal.Find(s => s.Name.StartsWith(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Test</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">));
</span><span style="color: rgba(0, 0, 255, 1)">foreach</span> (UserInfo info <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> members)
{
Console.WriteLine(info.Id </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)">"</span> +<span style="color: rgba(0, 0, 0, 1)"> info.Name);
}</span></pre>
</div>
<div class="cnblogs_code">
<pre> <span style="color: rgba(0, 0, 255, 1)">var</span> user = dal.FindSingle(s => s.Id == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">56815e6634ab091e1406ec68</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">if</span>(user != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
{
Console.WriteLine(user.Name);
}</span></pre>
</div>
<p>对于部分字段的更新处理,在界面上,我们可以利用封装好的接口进行处理,如下所示。</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span> btnAddAge_Click(<span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(0, 0, 0, 1)"> sender, EventArgs e)
{
UserInfo info </span>= dal.GetAll()[<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>(info != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
{
Console.WriteLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Age before Incr:</span><span style="color: rgba(128, 0, 0, 1)">"</span> +<span style="color: rgba(0, 0, 0, 1)"> info.Age);
</span><span style="color: rgba(0, 0, 255, 1)">int</span> addAge = <span style="color: rgba(128, 0, 128, 1)">10</span><span style="color: rgba(0, 0, 0, 1)">;
dal.IncreaseAge(info.Id, addAge);
info </span>=<span style="color: rgba(0, 0, 0, 1)"> dal.FindByID(info.Id);
Console.WriteLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Age after Incr:</span><span style="color: rgba(128, 0, 0, 1)">"</span> +<span style="color: rgba(0, 0, 0, 1)"> info.Age);
Console.WriteLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Name before modify:</span><span style="color: rgba(128, 0, 0, 1)">"</span> +<span style="color: rgba(0, 0, 0, 1)"> info.Name);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> update = Builders<UserInfo>.Update.Set(s => s.Name, info.Name +<span style="color: rgba(0, 0, 0, 1)"> DateTime.Now.Second);
dal.Update(info.Id, update);
info </span>=<span style="color: rgba(0, 0, 0, 1)"> dal.FindByID(info.Id);
Console.WriteLine(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Name after modify:</span><span style="color: rgba(128, 0, 0, 1)">"</span> +<span style="color: rgba(0, 0, 0, 1)"> info.Name);
}
}</span></pre>
</div>
<p>对于异步接口的调用代码,如下所示。</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></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)"></summary></span>
<span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">async</span> <span style="color: rgba(0, 0, 255, 1)">void</span> btnAsync_Click(<span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(0, 0, 0, 1)"> sender, EventArgs e)
{
UserInfo newInfo </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> UserInfo();
newInfo.Name </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Ping</span><span style="color: rgba(128, 0, 0, 1)">"</span> +<span style="color: rgba(0, 0, 0, 1)"> DateTime.Now.ToString();
newInfo.Age </span>=<span style="color: rgba(0, 0, 0, 1)"> DateTime.Now.Minute;
newInfo.Hobby </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)">"</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">await</span><span style="color: rgba(0, 0, 0, 1)"> dal.InsertAsync(newInfo);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> list = <span style="color: rgba(0, 0, 255, 1)">await</span> dal.FindAsync(s => s.Age < <span style="color: rgba(128, 0, 128, 1)">30</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">foreach</span> (UserInfo info <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> list)
{
Console.WriteLine(info.Id </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)">"</span> +<span style="color: rgba(0, 0, 0, 1)"> info.Name);
}
Console.WriteLine(newInfo.Id);
}</span></pre>
</div>
<p> </p>
</div>
<div id="MySignature" role="contentinfo">
<div style="border-right-color: #cccccc; border-right-width: 1px; border-right-style: solid; padding-right: 5px; border-top-color: #cccccc; border-top-width: 1px; border-top-style: solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left-color: #cccccc; border-left-width: 1px; border-left-style: solid; width: 98%; padding-top: 4px; border-bottom-color: #cccccc; border-bottom-width: 1px; border-bottom-style: solid; background-color: #eeeeee;">
<img src="http://www.cnblogs.com/Images/OutliningIndicators/None.gif" align="top" alt>
<span style="color: #000000"><span class="Apple-tab-span" style="white-space: pre"></span>
专注于代码生成工具、.Net/Python 框架架构及软件开发,以及各种Vue.js的前端技术应用。著有Winform开发框架/混合式开发框架、微信开发框架、Bootstrap开发框架、ABP开发框架、SqlSugar开发框架、Python开发框架等框架产品。
<br> 转载请注明出处:撰写人:伍华聪 http://www.iqidi.com <br> </span></div><br><br>
来源:https://www.cnblogs.com/wuhuacong/p/5123313.html
頁:
[1]