无敌覆三界 發表於 2018-9-27 16:08:00

在ASP.NET Core2上操作MongoDB就是能这么的简便酷爽(自动完成分库分表)

<p>NoSQL是泛指非关系型的数据库,现今在我们的项目中也多有使用,其独特的优点为我们的项目架构带来了不少亮点,而我们这里的主角(MongoDB)则是NoSQL数据库家族中的一种。事实上,NoSQL数据库的应用场景有很多,其最主要的目的就是为了能解决大规模数据集合多重数据种类带来的困难,及大数据应用的难题。</p>
<p>&nbsp;</p>
<p><strong><span style="font-size: x-large">MongoDB</span></strong></p>
<p>MongoDB是一个开源的文档型数据库,由C++语言编写,采用分布式的文件存储方案,而文件的存储格式为BSON。MongoDB支持的数据类型有很多种,如:String、Int、Float、Timestamp、Binary、Object、Date、Arrays等。而MongoDB的特点也有很多,如:强大的查询语言、支持索引、支持自动处理碎片、支持JAVA/C#/Python等多种开发语言、支持面向集合存储等。关于MongoDB的具体描述也可自行到其官网查看,我这里就不再过多啰嗦了,下面贴出与其几个相关的网址吧:</p>
<p>MongoDB官网:https://www.mongodb.com/</p>
<p>MongoDB官方的.NET API文档:http://api.mongodb.com/csharp/current/html/R_Project_CSharpDriverDocs.htm</p>
<p>MongoDB官方的github网址:https://github.com/mongodb/mongo</p>
<p>MongoDB可视化管理工具NoSQL Manager for MongoDB的官网:https://www.mongodbmanager.com/</p>
<p>&nbsp;</p>
<p><strong><span style="font-size: x-large">背景</span></strong></p>
<p>在大部分的项目中都会遇到要将短消息类型的数据(比如企业系统内的用户操作行为的“操作日记”数据、聊天通讯系统内的“对话记录”等数据)做持久化,而这种数据的特征就是关系简单、数据量庞大、大部分只有读写操作等。基于这些业务需要与应用场景,那么我们就可以考率使用MongoDB来做数据的持久化存储与管理了。</p>
<p>在这里,我们将模拟一个基于Saas平台下的企业系统内“操作日记”的业务场景(项目将以Saas服务提供给各个企业使用,并将所有用户在系统上的操作行为以日记方式存储到数据库去),并使用MongoDB来做数据的持久化存储与管理(包含对数据的增加与查询操作)。这里我们为了简便则将代码的结构层次分为两层(实际项目中各位按需分层级),那么项目结构将是这个样子的:</p>
<p>1、Lezhima.Web:接受来自客户端的请求,及服务端响应的出入口。由一个基于ASP.NET Core的MVC项目组成。</p>
<p>2、Lezhima.Data:直接跟MongoDB进行通讯交互,实现对DB的增、查等操作。由一个基于.NET Core的类库组成。</p>
<p>&nbsp;</p>
<p><strong>业务规则:</strong></p>
<p>基于上述的应用场景所悉,我们将面向的是企业客户,且是以Saas服务运行在云上的,则我们操作管理MongoDB时将面临如下几个规则(基于海量数据的读写考率):</p>
<p>1、希望数据能按企业ID分库,即各个企业的数据归档到其对应的独立库中。</p>
<p>2、能根据日期每天分表存储数据。</p>
<p>3、分库能按企业ID自动完成,分表能按日期自动完成。</p>
<p><strong>&nbsp;</strong></p>
<p><strong>与MongoDB通讯的API类库:</strong></p>
<p>我们将使用由MongoDB官方提供的API类库来与MongoDB进行通讯与交互,在Lezhima.Data项目中可通过NuGet管理器引用如下两个类库:</p>
<p>1、MongoDB.Bson</p>
<p>2、MongoDB.Driver</p>
<p>&nbsp;</p>
<p><strong><span style="font-size: x-large">实现代码</span></strong></p>
<p>通过上面的介绍,我们清楚了两个分层之间的功能与关系,那么接下来我们就分别来看看它们具体的代码,及操作MongoDB的简便酷爽吧。</p>
<p>1、我们先看看Lezhima.Data层的代码,首先定义一个名为“MongoDbContext”类,用于管理MongoDB的上下文,代码如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> <span style="color: rgba(0, 0, 255, 1)">using</span> System;
<span style="color: rgba(0, 128, 128, 1)">2</span> <span style="color: rgba(0, 0, 255, 1)">using</span> System.Collections.Generic;
<span style="color: rgba(0, 128, 128, 1)">3</span> <span style="color: rgba(0, 0, 255, 1)">using</span> System.Linq;
<span style="color: rgba(0, 128, 128, 1)">4</span> <span style="color: rgba(0, 0, 255, 1)">using</span> System.Runtime.InteropServices;
<span style="color: rgba(0, 128, 128, 1)">5</span> <span style="color: rgba(0, 0, 255, 1)">using</span> System.Security.Authentication;
<span style="color: rgba(0, 128, 128, 1)">6</span> <span style="color: rgba(0, 0, 255, 1)">using</span> System.Text.RegularExpressions;
<span style="color: rgba(0, 128, 128, 1)">7</span> <span style="color: rgba(0, 0, 255, 1)">using</span> System.Threading.Tasks;
<span style="color: rgba(0, 128, 128, 1)">8</span> <span style="color: rgba(0, 0, 255, 1)">using</span> MongoDB.Bson;
<span style="color: rgba(0, 128, 128, 1)">9</span> <span style="color: rgba(0, 0, 255, 1)">using</span> MongoDB.Driver;
<span style="color: rgba(0, 128, 128, 1)"> 10</span>
<span style="color: rgba(0, 128, 128, 1)"> 11</span> <span style="color: rgba(0, 0, 255, 1)">namespace</span> Lezhima.Data.Context
<span style="color: rgba(0, 128, 128, 1)"> 12</span> {
<span style="color: rgba(0, 128, 128, 1)"> 13</span>   <span style="color: rgba(128, 128, 128, 1)">/// &lt;summary&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 14</span>   <span style="color: rgba(128, 128, 128, 1)">/// MongoDB对象的上下文</span>
<span style="color: rgba(0, 128, 128, 1)"> 15</span>   <span style="color: rgba(128, 128, 128, 1)">/// &lt;/summary&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 16</span>   <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span> MongoDbContext
<span style="color: rgba(0, 128, 128, 1)"> 17</span>   {
<span style="color: rgba(0, 128, 128, 1)"> 18</span>
<span style="color: rgba(0, 128, 128, 1)"> 19</span>         
<span style="color: rgba(0, 128, 128, 1)"> 23</span>
<span style="color: rgba(0, 128, 128, 1)"> 24</span>
<span style="color: rgba(0, 128, 128, 1)"> 25</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;summary&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 26</span>         <span style="color: rgba(128, 128, 128, 1)">/// Mongo上下文 </span>
<span style="color: rgba(0, 128, 128, 1)"> 27</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;/summary&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 28</span>         <span style="color: rgba(0, 0, 255, 1)">public</span> IMongoDatabase DbContext { <span style="color: rgba(0, 0, 255, 1)">get</span>; }
<span style="color: rgba(0, 128, 128, 1)"> 29</span>
<span style="color: rgba(0, 128, 128, 1)"> 30</span>
<span style="color: rgba(0, 128, 128, 1)"> 31</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;summary&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 32</span>         <span style="color: rgba(128, 128, 128, 1)">/// 初始化MongoDb数据上下文</span>
<span style="color: rgba(0, 128, 128, 1)"> 33</span>         <span style="color: rgba(128, 128, 128, 1)">/// 将数据库名传递进来</span>
<span style="color: rgba(0, 128, 128, 1)"> 34</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;/summary&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 35</span>         <span style="color: rgba(0, 0, 255, 1)">public</span> MongoDbContext(<span style="color: rgba(0, 0, 255, 1)">string</span> dbName)
<span style="color: rgba(0, 128, 128, 1)"> 36</span>         {
<span style="color: rgba(0, 128, 128, 1)"> 37</span>             <span style="color: rgba(0, 128, 0, 1)">//连接字符串,如:"mongodb://username:password@host:port/?ssl=true"</span>
<span style="color: rgba(0, 128, 128, 1)"> 38</span>             <span style="color: rgba(0, 128, 0, 1)">//建议放在配置文件中</span>
<span style="color: rgba(0, 128, 128, 1)"> 39</span>             var connectionString = "<span style="color: rgba(139, 0, 0, 1)">mongodb://root:a123@192.168.1.6:27017</span>";
<span style="color: rgba(0, 128, 128, 1)"> 40</span>             <span style="color: rgba(0, 0, 255, 1)">try</span>
<span style="color: rgba(0, 128, 128, 1)"> 41</span>             {
<span style="color: rgba(0, 128, 128, 1)"> 42</span>               var mongoClient = <span style="color: rgba(0, 0, 255, 1)">new</span> MongoClient(connectionString);
<span style="color: rgba(0, 128, 128, 1)"> 43</span>               <span style="color: rgba(0, 128, 0, 1)">//数据库如果不存在,会自动创建</span>
<span style="color: rgba(0, 128, 128, 1)"> 44</span>               DbContext = mongoClient.GetDatabase(dbName);
<span style="color: rgba(0, 128, 128, 1)"> 45</span>             }
<span style="color: rgba(0, 128, 128, 1)"> 46</span>             <span style="color: rgba(0, 0, 255, 1)">catch</span> (Exception e)
<span style="color: rgba(0, 128, 128, 1)"> 47</span>             {
<span style="color: rgba(0, 128, 128, 1)"> 48</span>               Log.WriteLogByError("<span style="color: rgba(139, 0, 0, 1)">构建MongoDbContext出错</span>", e);
<span style="color: rgba(0, 128, 128, 1)"> 49</span>               <span style="color: rgba(0, 0, 255, 1)">throw</span>;
<span style="color: rgba(0, 128, 128, 1)"> 50</span>             }
<span style="color: rgba(0, 128, 128, 1)"> 51</span>         }
<span style="color: rgba(0, 128, 128, 1)"> 52</span>
<span style="color: rgba(0, 128, 128, 1)"> 53</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;summary&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 54</span>         <span style="color: rgba(128, 128, 128, 1)">/// 异步获取表(集合)</span>
<span style="color: rgba(0, 128, 128, 1)"> 55</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;/summary&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 56</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;typeparam name="TEntity"&gt;&lt;/typeparam&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 57</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;param name="datetime"&gt;&lt;/param&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 58</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;returns&gt;&lt;/returns&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 59</span>         <span style="color: rgba(0, 0, 255, 1)">public</span> async Task&lt;IMongoCollection&lt;TEntity&gt;&gt; GetCollectionAsync&lt;TEntity&gt;(<span style="color: rgba(0, 0, 255, 1)">string</span> tableName="") where TEntity : <span style="color: rgba(0, 0, 255, 1)">class</span>
<span style="color: rgba(0, 128, 128, 1)"> 60</span>         {
<span style="color: rgba(0, 128, 128, 1)"> 61</span>            
<span style="color: rgba(0, 128, 128, 1)"> 66</span>
<span style="color: rgba(0, 128, 128, 1)"> 67</span>             var dt = DateTime.Now.ToString("<span style="color: rgba(139, 0, 0, 1)">yyyy -MM-dd</span>");
<span style="color: rgba(0, 128, 128, 1)"> 68</span>
<span style="color: rgba(0, 128, 128, 1)"> 69</span>             <span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 255, 1)">string</span>.IsNullOrEmpty(tableName))
<span style="color: rgba(0, 128, 128, 1)"> 70</span>             {
<span style="color: rgba(0, 128, 128, 1)"> 71</span>
<span style="color: rgba(0, 128, 128, 1)"> 72</span>               dt = tableName;
<span style="color: rgba(0, 128, 128, 1)"> 73</span>             }
<span style="color: rgba(0, 128, 128, 1)"> 74</span>
<span style="color: rgba(0, 128, 128, 1)"> 75</span>             <span style="color: rgba(0, 128, 0, 1)">// 获取集合名称,使用的标准是在实体类型名后添加日期</span>
<span style="color: rgba(0, 128, 128, 1)"> 76</span>             var collectionName = dt;
<span style="color: rgba(0, 128, 128, 1)"> 77</span>
<span style="color: rgba(0, 128, 128, 1)"> 78</span>             <span style="color: rgba(0, 128, 0, 1)">// 如果集合不存在,那么创建集合</span>
<span style="color: rgba(0, 128, 128, 1)"> 79</span>             <span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 0, 255, 1)">false</span> == await IsCollectionExistsAsync&lt;TEntity&gt;(collectionName))
<span style="color: rgba(0, 128, 128, 1)"> 80</span>             {
<span style="color: rgba(0, 128, 128, 1)"> 81</span>               await DbContext.CreateCollectionAsync(collectionName);
<span style="color: rgba(0, 128, 128, 1)"> 82</span>             }
<span style="color: rgba(0, 128, 128, 1)"> 83</span>
<span style="color: rgba(0, 128, 128, 1)"> 84</span>         
<span style="color: rgba(0, 128, 128, 1)"> 87</span>             <span style="color: rgba(0, 0, 255, 1)">return</span> DbContext.GetCollection&lt;TEntity&gt;(collectionName);
<span style="color: rgba(0, 128, 128, 1)"> 92</span>         }
<span style="color: rgba(0, 128, 128, 1)"> 93</span>
<span style="color: rgba(0, 128, 128, 1)"> 94</span>
<span style="color: rgba(0, 128, 128, 1)"> 95</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;summary&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 96</span>         <span style="color: rgba(128, 128, 128, 1)">/// 集合是否存在</span>
<span style="color: rgba(0, 128, 128, 1)"> 97</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;/summary&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 98</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;typeparam name="TEntity"&gt;&lt;/typeparam&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 99</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;returns&gt;&lt;/returns&gt;</span>
<span style="color: rgba(0, 128, 128, 1)">100</span>         <span style="color: rgba(0, 0, 255, 1)">public</span> async Task&lt;<span style="color: rgba(0, 0, 255, 1)">bool</span>&gt; IsCollectionExistsAsync&lt;TEntity&gt;(<span style="color: rgba(0, 0, 255, 1)">string</span> name)
<span style="color: rgba(0, 128, 128, 1)">101</span>         {
<span style="color: rgba(0, 128, 128, 1)">102</span>             var filter = <span style="color: rgba(0, 0, 255, 1)">new</span> BsonDocument("<span style="color: rgba(139, 0, 0, 1)">name</span>", name);
<span style="color: rgba(0, 128, 128, 1)">103</span>             <span style="color: rgba(0, 128, 0, 1)">// 通过集合名称过滤</span>
<span style="color: rgba(0, 128, 128, 1)">104</span>             var collections = await DbContext.ListCollectionsAsync(<span style="color: rgba(0, 0, 255, 1)">new</span> ListCollectionsOptions { Filter = filter });
<span style="color: rgba(0, 128, 128, 1)">105</span>             <span style="color: rgba(0, 128, 0, 1)">// 检查是否存在</span>
<span style="color: rgba(0, 128, 128, 1)">106</span>             <span style="color: rgba(0, 0, 255, 1)">return</span> await collections.AnyAsync();
<span style="color: rgba(0, 128, 128, 1)">107</span>         }
<span style="color: rgba(0, 128, 128, 1)">108</span>   }
<span style="color: rgba(0, 128, 128, 1)">109</span> }</pre>
</div>
<p>&nbsp;</p>
<p>2、在Lezhima.Data层增加一个名为“IMongoRepository”接口,用于封装向业务层提供操作MongoDB的操作方法,代码如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> <span style="color: rgba(0, 0, 255, 1)">using</span> System;
<span style="color: rgba(0, 128, 128, 1)">2</span> <span style="color: rgba(0, 0, 255, 1)">using</span> System.Collections.Generic;
<span style="color: rgba(0, 128, 128, 1)">3</span> <span style="color: rgba(0, 0, 255, 1)">using</span> System.Linq;
<span style="color: rgba(0, 128, 128, 1)">4</span> <span style="color: rgba(0, 0, 255, 1)">using</span> System.Linq.Expressions;
<span style="color: rgba(0, 128, 128, 1)">5</span> <span style="color: rgba(0, 0, 255, 1)">using</span> System.Text;
<span style="color: rgba(0, 128, 128, 1)">6</span> <span style="color: rgba(0, 0, 255, 1)">using</span> System.Threading.Tasks;
<span style="color: rgba(0, 128, 128, 1)">7</span> <span style="color: rgba(0, 0, 255, 1)">using</span> MongoDB.Bson;
<span style="color: rgba(0, 128, 128, 1)">8</span> <span style="color: rgba(0, 0, 255, 1)">using</span> MongoDB.Driver;
<span style="color: rgba(0, 128, 128, 1)">9</span>
<span style="color: rgba(0, 128, 128, 1)"> 10</span> <span style="color: rgba(0, 0, 255, 1)">namespace</span> Lezhima.Data.Interface
<span style="color: rgba(0, 128, 128, 1)"> 11</span> {
<span style="color: rgba(0, 128, 128, 1)"> 12</span>   <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">interface</span> IMongoRepository&lt;T&gt; where T : <span style="color: rgba(0, 0, 255, 1)">class</span>
<span style="color: rgba(0, 128, 128, 1)"> 13</span>   {
<span style="color: rgba(0, 128, 128, 1)"> 14</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;summary&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 15</span>         <span style="color: rgba(128, 128, 128, 1)">/// 从指定的库与表中获取指定条件的数据</span>
<span style="color: rgba(0, 128, 128, 1)"> 16</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;/summary&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 17</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;returns&gt;&lt;/returns&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 18</span>         Task&lt;List&lt;T&gt;&gt; GetListAsync(Expression&lt;Func&lt;T, <span style="color: rgba(0, 0, 255, 1)">bool</span>&gt;&gt; predicate, <span style="color: rgba(0, 0, 255, 1)">string</span> dbName, <span style="color: rgba(0, 0, 255, 1)">string</span> tableName = "");
<span style="color: rgba(0, 128, 128, 1)"> 19</span>
<span style="color: rgba(0, 128, 128, 1)"> 20</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;summary&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 21</span>         <span style="color: rgba(128, 128, 128, 1)">/// 对指定的库与表中新增数据</span>
<span style="color: rgba(0, 128, 128, 1)"> 22</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;/summary&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 23</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;returns&gt;&lt;/returns&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 24</span>         Task&lt;<span style="color: rgba(0, 0, 255, 1)">bool</span>&gt; Add(List&lt;T&gt; list, <span style="color: rgba(0, 0, 255, 1)">string</span> dbName, <span style="color: rgba(0, 0, 255, 1)">string</span> tableName = "");
<span style="color: rgba(0, 128, 128, 1)"> 25</span>   }
<span style="color: rgba(0, 128, 128, 1)"> 26</span> }
<span style="color: rgba(0, 128, 128, 1)"> 27</span> </pre>
</div>
<p>&nbsp;</p>
<p>3、在Lezhima.Data层再增加一个名为“MongoRepository”类,实现“IMongoRepository”接口,代码如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> <span style="color: rgba(0, 0, 255, 1)">using</span> System;
<span style="color: rgba(0, 128, 128, 1)">2</span> <span style="color: rgba(0, 0, 255, 1)">using</span> System.Collections.Generic;
<span style="color: rgba(0, 128, 128, 1)">3</span> <span style="color: rgba(0, 0, 255, 1)">using</span> System.Linq;
<span style="color: rgba(0, 128, 128, 1)">4</span> <span style="color: rgba(0, 0, 255, 1)">using</span> System.Linq.Expressions;
<span style="color: rgba(0, 128, 128, 1)">5</span> <span style="color: rgba(0, 0, 255, 1)">using</span> System.Threading.Tasks;
<span style="color: rgba(0, 128, 128, 1)">6</span> <span style="color: rgba(0, 0, 255, 1)">using</span> System.Web;
<span style="color: rgba(0, 128, 128, 1)">7</span> <span style="color: rgba(0, 0, 255, 1)">using</span> Lezhima.Data.Context;
<span style="color: rgba(0, 128, 128, 1)">8</span> <span style="color: rgba(0, 0, 255, 1)">using</span> Lezhima.Data.Interface;
<span style="color: rgba(0, 128, 128, 1)">9</span> <span style="color: rgba(0, 0, 255, 1)">using</span> MongoDB.Bson;
<span style="color: rgba(0, 128, 128, 1)"> 10</span> <span style="color: rgba(0, 0, 255, 1)">using</span> MongoDB.Driver;
<span style="color: rgba(0, 128, 128, 1)"> 11</span>
<span style="color: rgba(0, 128, 128, 1)"> 12</span>
<span style="color: rgba(0, 128, 128, 1)"> 13</span> <span style="color: rgba(0, 0, 255, 1)">namespace</span> Lezhima.Data
<span style="color: rgba(0, 128, 128, 1)"> 14</span> {
<span style="color: rgba(0, 128, 128, 1)"> 15</span>   <span style="color: rgba(128, 128, 128, 1)">/// &lt;summary&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 16</span>   <span style="color: rgba(128, 128, 128, 1)">/// 封装向业务层提供操作MongoDB的操作方法</span>
<span style="color: rgba(0, 128, 128, 1)"> 17</span>   <span style="color: rgba(128, 128, 128, 1)">/// &lt;/summary&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 18</span>   <span style="color: rgba(128, 128, 128, 1)">/// &lt;typeparam name="T"&gt;&lt;/typeparam&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 19</span>   <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span> MongoRepository&lt;T&gt; : IMongoRepository&lt;T&gt; where T : <span style="color: rgba(0, 0, 255, 1)">class</span>
<span style="color: rgba(0, 128, 128, 1)"> 20</span>   {
<span style="color: rgba(0, 128, 128, 1)"> 21</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;summary&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 22</span>         <span style="color: rgba(128, 128, 128, 1)">/// 从指定的库与表中获取指定条件的数据</span>
<span style="color: rgba(0, 128, 128, 1)"> 23</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;/summary&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 24</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;returns&gt;&lt;/returns&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 25</span>         <span style="color: rgba(0, 0, 255, 1)">public</span> async Task&lt;List&lt;T&gt;&gt; GetListAsync(Expression&lt;Func&lt;T, <span style="color: rgba(0, 0, 255, 1)">bool</span>&gt;&gt; predicate, <span style="color: rgba(0, 0, 255, 1)">string</span> dbName, <span style="color: rgba(0, 0, 255, 1)">string</span> tableName)
<span style="color: rgba(0, 128, 128, 1)"> 26</span>         {
<span style="color: rgba(0, 128, 128, 1)"> 27</span>             var dbContext = <span style="color: rgba(0, 0, 255, 1)">new</span> MongoDbContext(dbName);
<span style="color: rgba(0, 128, 128, 1)"> 28</span>             var collection = await dbContext.GetCollectionAsync&lt;T&gt;(tableName);
<span style="color: rgba(0, 128, 128, 1)"> 29</span>             <span style="color: rgba(0, 0, 255, 1)">return</span> collection.AsQueryable&lt;T&gt;().Where(predicate).ToList();
<span style="color: rgba(0, 128, 128, 1)"> 30</span>         }
<span style="color: rgba(0, 128, 128, 1)"> 31</span>
<span style="color: rgba(0, 128, 128, 1)"> 32</span>
<span style="color: rgba(0, 128, 128, 1)"> 33</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;summary&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 34</span>         <span style="color: rgba(128, 128, 128, 1)">/// 对指定的库与表中新增数据</span>
<span style="color: rgba(0, 128, 128, 1)"> 35</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;/summary&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 36</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;returns&gt;&lt;/returns&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 37</span>         <span style="color: rgba(0, 0, 255, 1)">public</span> async Task&lt;<span style="color: rgba(0, 0, 255, 1)">bool</span>&gt; Add(List&lt;T&gt; list, <span style="color: rgba(0, 0, 255, 1)">string</span> dbName, <span style="color: rgba(0, 0, 255, 1)">string</span> tableName = "")
<span style="color: rgba(0, 128, 128, 1)"> 38</span>         {
<span style="color: rgba(0, 128, 128, 1)"> 39</span>             var dbContext = <span style="color: rgba(0, 0, 255, 1)">new</span> MongoDbContext(dbName);
<span style="color: rgba(0, 128, 128, 1)"> 40</span>             var collection = await dbContext.GetCollectionAsync&lt;T&gt;(tableName);
<span style="color: rgba(0, 128, 128, 1)"> 41</span>             await collection.InsertManyAsync(list);
<span style="color: rgba(0, 128, 128, 1)"> 42</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, 128, 128, 1)"> 43</span>         }
<span style="color: rgba(0, 128, 128, 1)"> 44</span>   }
<span style="color: rgba(0, 128, 128, 1)"> 45</span> }
<span style="color: rgba(0, 128, 128, 1)"> 46</span> </pre>
</div>
<p>&nbsp;</p>
<p>4、在Lezhima.Web层再增加一个名为“TestController”的控制器,用于向用户提供测试读写MongoDB操作的出入口,代码如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> <span style="color: rgba(0, 0, 255, 1)">using</span> System;
<span style="color: rgba(0, 128, 128, 1)">2</span> <span style="color: rgba(0, 0, 255, 1)">using</span> System.Collections.Generic;
<span style="color: rgba(0, 128, 128, 1)">3</span> <span style="color: rgba(0, 0, 255, 1)">using</span> System.Linq;
<span style="color: rgba(0, 128, 128, 1)">4</span> <span style="color: rgba(0, 0, 255, 1)">using</span> System.Threading.Tasks;
<span style="color: rgba(0, 128, 128, 1)">5</span> <span style="color: rgba(0, 0, 255, 1)">using</span> Lezhima.Core;
<span style="color: rgba(0, 128, 128, 1)">6</span> <span style="color: rgba(0, 0, 255, 1)">using</span> Lezhima.Data.Interface;
<span style="color: rgba(0, 128, 128, 1)">7</span> <span style="color: rgba(0, 0, 255, 1)">using</span> Microsoft.AspNetCore.Mvc;
<span style="color: rgba(0, 128, 128, 1)">8</span>
<span style="color: rgba(0, 128, 128, 1)">9</span> <span style="color: rgba(0, 0, 255, 1)">namespace</span> Lezhima.Web.Controllers
<span style="color: rgba(0, 128, 128, 1)"> 10</span> {
<span style="color: rgba(0, 128, 128, 1)"> 11</span>   </span>")]
<span style="color: rgba(0, 128, 128, 1)"> 12</span>   <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span> TestController : Controller
<span style="color: rgba(0, 128, 128, 1)"> 13</span>   {
<span style="color: rgba(0, 128, 128, 1)"> 14</span>         <span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span> IMongoRepository&lt;ActionLog&gt; _IMongoRepository;
<span style="color: rgba(0, 128, 128, 1)"> 15</span>
<span style="color: rgba(0, 128, 128, 1)"> 16</span>         <span style="color: rgba(0, 0, 255, 1)">public</span> TestController(IMongoRepository&lt;ActionLog&gt; __IMongoRepository)
<span style="color: rgba(0, 128, 128, 1)"> 17</span>         {
<span style="color: rgba(0, 128, 128, 1)"> 18</span>             _IMongoRepository = __IMongoRepository;
<span style="color: rgba(0, 128, 128, 1)"> 19</span>         }
<span style="color: rgba(0, 128, 128, 1)"> 20</span>
<span style="color: rgba(0, 128, 128, 1)"> 21</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;summary&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 22</span>         <span style="color: rgba(128, 128, 128, 1)">/// 测试新增数据方法</span>
<span style="color: rgba(0, 128, 128, 1)"> 23</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;/summary&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 24</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;returns&gt;&lt;/returns&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 25</span>         
<span style="color: rgba(0, 128, 128, 1)"> 26</span>         <span style="color: rgba(0, 0, 255, 1)">public</span> async Task&lt;<span style="color: rgba(0, 0, 255, 1)">string</span>&gt; Add()
<span style="color: rgba(0, 128, 128, 1)"> 27</span>         {
<span style="color: rgba(0, 128, 128, 1)"> 28</span>             <span style="color: rgba(0, 128, 0, 1)">//创建两个不同企业ID的实体数据</span>
<span style="color: rgba(0, 128, 128, 1)"> 29</span>             var model1 = <span style="color: rgba(0, 0, 255, 1)">new</span> ActionLog();
<span style="color: rgba(0, 128, 128, 1)"> 30</span>             model1.CompanyId = Guid.Parse("<span style="color: rgba(139, 0, 0, 1)">B29BC831-A974-4114-90E2-0001E03FBCAF</span>");
<span style="color: rgba(0, 128, 128, 1)"> 31</span>             model1.ActionLogId = Guid.NewGuid();
<span style="color: rgba(0, 128, 128, 1)"> 32</span>             model1.Context = "<span style="color: rgba(139, 0, 0, 1)">测试企业1</span>";
<span style="color: rgba(0, 128, 128, 1)"> 33</span>             model1.CreateTime = DateTime.Now;
<span style="color: rgba(0, 128, 128, 1)"> 34</span>             model1.UpdateTime = DateTime.Now;
<span style="color: rgba(0, 128, 128, 1)"> 35</span>
<span style="color: rgba(0, 128, 128, 1)"> 36</span>             var model2 = <span style="color: rgba(0, 0, 255, 1)">new</span> ActionLog();
<span style="color: rgba(0, 128, 128, 1)"> 37</span>             model2.CompanyId = Guid.Parse("<span style="color: rgba(139, 0, 0, 1)">651bbe49-a4c8-4514-babb-897dad7065e3</span>");
<span style="color: rgba(0, 128, 128, 1)"> 38</span>             model2.ActionLogId = Guid.NewGuid();
<span style="color: rgba(0, 128, 128, 1)"> 39</span>             model2.Context = "<span style="color: rgba(139, 0, 0, 1)">测试企业2</span>";
<span style="color: rgba(0, 128, 128, 1)"> 40</span>             model2.CreateTime = DateTime.Now;
<span style="color: rgba(0, 128, 128, 1)"> 41</span>             model2.UpdateTime = DateTime.Now;
<span style="color: rgba(0, 128, 128, 1)"> 42</span>
<span style="color: rgba(0, 128, 128, 1)"> 43</span>
<span style="color: rgba(0, 128, 128, 1)"> 44</span>             var list = <span style="color: rgba(0, 0, 255, 1)">new</span> List&lt;ActionLog&gt;();
<span style="color: rgba(0, 128, 128, 1)"> 45</span>             list.Add(model1);
<span style="color: rgba(0, 128, 128, 1)"> 46</span>             list.Add(model2);
<span style="color: rgba(0, 128, 128, 1)"> 47</span>
<span style="color: rgba(0, 128, 128, 1)"> 48</span>             var group_list = list.GroupBy(p =&gt; p.CompanyId);
<span style="color: rgba(0, 128, 128, 1)"> 49</span>             var tableName = "<span style="color: rgba(139, 0, 0, 1)">ActionLog_</span>" + DateTime.Now.ToString("<span style="color: rgba(139, 0, 0, 1)">yyyy-MM-dd</span>");
<span style="color: rgba(0, 128, 128, 1)"> 50</span>             <span style="color: rgba(0, 0, 255, 1)">foreach</span> (var group <span style="color: rgba(0, 0, 255, 1)">in</span> group_list)
<span style="color: rgba(0, 128, 128, 1)"> 51</span>             {
<span style="color: rgba(0, 128, 128, 1)"> 52</span>               var dbName = "<span style="color: rgba(139, 0, 0, 1)">ActionLog_</span>" + group.FirstOrDefault().CompanyId.ToString();
<span style="color: rgba(0, 128, 128, 1)"> 53</span>
<span style="color: rgba(0, 128, 128, 1)"> 54</span>               await _IMongoRepository.Add(group.ToList(), dbName, tableName);
<span style="color: rgba(0, 128, 128, 1)"> 55</span>             }
<span style="color: rgba(0, 128, 128, 1)"> 56</span>
<span style="color: rgba(0, 128, 128, 1)"> 57</span>             <span style="color: rgba(0, 0, 255, 1)">return</span> "<span style="color: rgba(139, 0, 0, 1)">value1</span>";
<span style="color: rgba(0, 128, 128, 1)"> 58</span>         }
<span style="color: rgba(0, 128, 128, 1)"> 59</span>
<span style="color: rgba(0, 128, 128, 1)"> 60</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;summary&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 61</span>         <span style="color: rgba(128, 128, 128, 1)">/// 测试查询方法</span>
<span style="color: rgba(0, 128, 128, 1)"> 62</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;/summary&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 63</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;param name="companyId"&gt;&lt;/param&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 64</span>         <span style="color: rgba(128, 128, 128, 1)">/// &lt;returns&gt;&lt;/returns&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 65</span>         
<span style="color: rgba(0, 128, 128, 1)"> 66</span>         <span style="color: rgba(0, 0, 255, 1)">public</span> async Task&lt;List&lt;ActionLog&gt;&gt; Get(Guid companyId)
<span style="color: rgba(0, 128, 128, 1)"> 67</span>         {
<span style="color: rgba(0, 128, 128, 1)"> 68</span>             var dbName = "<span style="color: rgba(139, 0, 0, 1)">ActionLog_</span>" + companyId.ToString();
<span style="color: rgba(0, 128, 128, 1)"> 69</span>             var tableName = "<span style="color: rgba(139, 0, 0, 1)">ActionLog_</span>" + DateTime.Now.ToString("<span style="color: rgba(139, 0, 0, 1)">yyyy-MM-dd</span>");
<span style="color: rgba(0, 128, 128, 1)"> 70</span>             var list = await _IMongoRepository.GetListAsync(p =&gt; p.Context.IndexOf("<span style="color: rgba(139, 0, 0, 1)">测试企业</span>") &gt; -1, dbName, tableName);
<span style="color: rgba(0, 128, 128, 1)"> 71</span>             <span style="color: rgba(0, 0, 255, 1)">return</span> list;
<span style="color: rgba(0, 128, 128, 1)"> 72</span>         }
<span style="color: rgba(0, 128, 128, 1)"> 73</span>
<span style="color: rgba(0, 128, 128, 1)"> 74</span>   }
<span style="color: rgba(0, 128, 128, 1)"> 75</span> }
<span style="color: rgba(0, 128, 128, 1)"> 76</span> </pre>
</div>
<p>&nbsp;</p>
<p><strong><span style="font-size: x-large">总结</span></strong></p>
<p>1、MongoDB是开源的文档型非关系型数据库,支持JAVA/C#/Python等多种开发语言。</p>
<p>2、通过由MongoDB官方提供的两个API类库实现跟MongoDB通讯交互。</p>
<p>3、MongoDB不需要提前创建数据库与表结构,其会通过传递进去的数据结构自动判断是否需要维护库与表的结构,这个机制对我们项目的大部分场景都很实用。</p>
<p>4、最后再通过对Lezhima.Data层简单的封装后,使得面向业务层的调用非常简便。</p>
<p>&nbsp;</p>
<p><strong><span style="font-size: x-large">声明</span></strong></p>
<p>本文为作者原创,转载请备注出处与保留原文地址,谢谢。如文章能给您带来帮助,请点下推荐或关注,感谢您的支持!</p>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/maixinda/p/9712245.html
頁: [1]
查看完整版本: 在ASP.NET Core2上操作MongoDB就是能这么的简便酷爽(自动完成分库分表)