MongoDB 工具助手类(.NET) - jiangys - 博客园

mikel阅读(583)

来源: MongoDB 工具助手类(.NET) – jiangys – 博客园

在开发过程中,需要用到MongoDB,本身MongoDB自己对类的封装就特别好了。为了更加符合我们平时的开发使用,我现在进行了一个简单的封装操作。

连接数据库类:MongoDBContext

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Configuration;

using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
using MongoDB.Driver.Linq;

namespace XXXXX.MongoDB
{
    public class MongoDBContext
    {
        // 数据库链接
        private readonly MongoDatabase database;

        public MongoDBContext()
            : this(ConfigurationManager.AppSettings["DefaultMongoDBConnection"], ConfigurationManager.AppSettings["DefaultMonoDbDatabase"])
        {
        }

        /// <summary>
        /// 构造函数。根据指定连接字符串和数据库名
        /// </summary>
        /// <param name="connectionString">连接字符串</param>
        /// <param name="dbName">数据库名</param>
        public MongoDBContext(string connectionString, string dbName)
        {
            if (string.IsNullOrEmpty(connectionString))
            {
                throw new ArgumentNullException("connectionString is null");
            }

            if (string.IsNullOrEmpty(dbName))
            {
                throw new ArgumentNullException("dbName is null");
            }

            var client = new MongoClient(connectionString);
            var server = client.GetServer();
            this.database = server.GetDatabase(dbName);
        }

        /// <summary>
        /// 获取当前连接数据库的指定集合【依据类型】
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public MongoCollection<T> Collection<T>()
        {
            return database.GetCollection<T>(typeof(T).Name);
        }
    }
}
复制代码

服务操作类:MongoDBService

复制代码
using MongoDB.Driver.Builders;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace XXXXX.MongoDB
{

    public class MongoDBService<T> : IMongoDBService<T> where T : class,new()
    {
        MongoDBContext mc = new MongoDBContext();

        /// <summary>
        /// 查询符合条件的集合
        /// </summary>
        /// <param name="whereLambda"></param>
        /// <returns></returns>
        public IEnumerable<T> GetList()
        {
            var query = Query<T>.Where(o => true);
            return mc.Collection<T>().Find(query);
        }

        /// <summary>
        /// 查询符合条件的集合
        /// </summary>
        /// <param name="whereLambda"></param>
        /// <returns></returns>
        public IEnumerable<T> GetList(Expression<Func<T, bool>> whereLambda)
        {
            var query = Query<T>.Where(whereLambda);
            return mc.Collection<T>().Find(query);
        }

        /// <summary>
        /// 查询一条记录
        /// </summary>
        /// <param name="whereLambda"></param>
        /// <returns></returns>
        public T GetOne(Expression<Func<T, bool>> whereLambda)
        {
            var query = GetList(whereLambda).FirstOrDefault();
            return query;
        }

        /// <summary>
        /// 增加
        /// </summary>
        /// <param name="entity"></param>
        public void Insert(T entity)
        {
            mc.Collection<T>().Insert(entity);
        }

        /// <summary>
        /// 批量增加
        /// </summary>
        /// <param name="entitys"></param>
        public void InsertAll(IEnumerable<T> entitys)
        {
            mc.Collection<T>().InsertBatch(entitys);
        }

        /// <summary>
        /// 更新一个实体
        /// </summary>
        /// <param name="entity"></param>
        public void Update(T entity)
        {
            mc.Collection<T>().Save(entity);
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="whereLambda"></param>
        public void Remove(Expression<Func<T, bool>> whereLambda)
        {
            var query = Query<T>.Where(whereLambda);
            mc.Collection<T>().Remove(query);
        }
    }
}
复制代码

上面方法封装完后,我们就可以直接使用了。使用很简单,比如,我有一个ActivityModel实体,使用时,如下:

复制代码
        public void activityTest()
        {
            var activityDb = new MongoDBService<ActivityModel>();
            var activityList = activityDb.GetList().ToList();
            var activity = activityDb.GetOne(o => o.Id==ObjectId.Parse("54d9aecd89f0bd14d81a63a7"));
            var xxx = activity.To();
        }
复制代码

 

双十一来了,别让你的mongodb宕机了 - 一线码农 - 博客园

mikel阅读(612)

来源: 双十一来了,别让你的mongodb宕机了 – 一线码农 – 博客园

 

好久没过来吹牛了,前段时间一直赶项目,没有时间来更新博客,项目也终于赶完了,接下来就要面临双十一这场惊心动魄的处女秀考验,

我们项目中会有一个wcf集群,而集群地址则放在mongodb中,所以mongodb的核心地位可想而知,如果mongodb挂掉,整个项目也就陷入

瘫痪,想让mongodb不宕机,最简单的方法就是要做双机热备,跟传统的关系型数据库的双机热备模式一样,一个主服务器,一个备份服务器,

一个仲裁服务器。如果热备集群中的主服务器宕掉,会有仲裁服务器参与投票来选出一台作为主服务器,我想这个大家都比较清楚,下面我们来

实战一下,最后会奉献源代码。

 

一:搭建mongodb热备集群

1. 准备工作

为了做到最简化搭建,我就做一个主,一个备,一个仲裁就好了,然后最简化配置信息都放在mongodb.conf文件中,如下图:

 

从上图中可以看到,三个mongodb,我建立了对应的三个文件夹来存放对应的三个db,其中“主服务器”的端口为27000,“备服务器“的端口为

27001,”仲裁服务器“端口为27002。 具体mongodb.conf内容如下:

 

2. 开启 “主服务器” 【27000】

 

3.  开启 “备服务器” 【27001】

 

4.  开启 “仲裁服务器” 【27002】

 

现在三台服务器都开启起来了,细心的你会发现,三个控制台都有这么一段英文单词” replSet info you may need to run replSetInitiate“。。。

既然都这么说了,我现在就去run这个func。

 

复制代码
db.runCommand({
    "replSetInitiate":{
        "_id":"datamip",
        "members":[
            {
                "_id":1,
                "host":"127.0.0.1:27000"
            },
            {
                "_id":2,
                "host":"127.0.0.1:27001"
            }
        ]
    }
})
复制代码

 

配置完了之后,然后我们把“仲裁服务器【27002】”加入到“datamip”这个双机热备分集群中。

 

rs.addArb( { host: "127.0.0.1:27002"} )

 

这个命令可以参考下官网的介绍:https://docs.mongodb.com/manual/reference/command/replSetInitiate/   好了,现在大致配置好了,接下

来我们用rs.Status()来查看下当前“主,备,仲裁”的分布情况。

 

从图中你应该看到了【27000】成为了主服务器,【27001】成为了备服务器,【27002】成为了仲裁服务器,到目前为止,搭建完成,是不是有

一个很爽的感觉呢???

 

三:使用驱动

既然mongodb的双机热备已经做好了,我们驱动也必须支持,这样我们才能够嗨,对伐???其实在配置中使用也很简单,里面有一个

MongoClientSettings,你需要配置一下”ReplicaSetName“和”Servers“列表即可,核心代码如下:

复制代码
 1         static MongoDBHelper()
 2         {
 3             var ips = connectionString.Split(';');
 4 
 5             var servicesList = new List<MongoServerAddress>();
 6 
 7             foreach (var ip in ips)
 8             {
 9                 var host = ip.Split(':')[0];
10                 var port = Convert.ToInt32(ip.Split(':')[1]);
11 
12                 servicesList.Add(new MongoServerAddress(host, port));
13             }
14 
15             setting = new MongoClientSettings();
16             setting.ReplicaSetName = "datamip";
17 
18             //集群中的服务器列表
19             setting.Servers = servicesList;
20         }
复制代码

 

其中ips的信息是配置在app.config中。

 <appSettings>
    <add key="mongodbServerList" value="127.0.0.1:27000;127.0.0.1:27001;127.0.0.1:27002"/>
  </appSettings>

 

然后我简单的封装了下mongodb。

复制代码
  1 namespace DataMipCRM.Common
  2 {
  3     public class MongoDBHelper<T>
  4     {
  5         private static readonly string connectionString = ConfigurationManager.AppSettings["mongodbServerList"];
  6 
  7         static MongoClientSettings setting = null;
  8         MongoServer server = null;
  9 
 10         public string tableName = "person";
 11 
 12         public string databaseName = "test";
 13 
 14         static MongoDBHelper()
 15         {
 16             var ips = connectionString.Split(';');
 17 
 18             var servicesList = new List<MongoServerAddress>();
 19 
 20             foreach (var ip in ips)
 21             {
 22                 var host = ip.Split(':')[0];
 23                 var port = Convert.ToInt32(ip.Split(':')[1]);
 24 
 25                 servicesList.Add(new MongoServerAddress(host, port));
 26             }
 27 
 28             setting = new MongoClientSettings();
 29             setting.ReplicaSetName = "datamip";
 30 
 31             //集群中的服务器列表
 32             setting.Servers = servicesList;
 33         }
 34 
 35         public MongoDBHelper(string databaseName, string tableName)
 36         {
 37             this.databaseName = databaseName;
 38             this.tableName = tableName;
 39 
 40             server = new MongoClient(setting).GetServer();
 41         }
 42 
 43         public bool Remove(Expression<Func<T, bool>> func)
 44         {
 45             try
 46             {
 47                 var database = server.GetDatabase(databaseName);
 48 
 49                 var collection = database.GetCollection<T>(tableName);
 50 
 51                 var query = Query<T>.Where(func);
 52 
 53                 var result = collection.Remove(query);
 54 
 55                 return result.Response["ok"].AsInt32 > 0 ? true : false;
 56             }
 57             catch (Exception ex)
 58             {
 59                 return false;
 60             }
 61         }
 62 
 63         public bool RemoveAll()
 64         {
 65             try
 66             {
 67                 var database = server.GetDatabase(databaseName);   //mongodb中的数据库
 68 
 69                 var collection = database.GetCollection<T>(tableName);
 70 
 71                 var result = collection.RemoveAll();
 72 
 73                 return result.Response["ok"].AsInt32 > 0 ? true : false;
 74             }
 75             catch (Exception ex)
 76             {
 77                 return false;
 78             }
 79         }
 80 
 81         #region 单条插入
 82         /// <summary>
 83         /// 单条插入
 84         /// </summary>
 85         /// <typeparam name="T"></typeparam>
 86         /// <param name="t"></param>
 87         public bool Insert(T t)
 88         {
 89             try
 90             {
 91                 var database = server.GetDatabase(databaseName);   //mongodb中的数据库
 92 
 93                 var collection = database.GetCollection<T>(tableName);
 94 
 95                 var result = collection.Insert(t);
 96                 return result.DocumentsAffected > 0;
 97             }
 98             catch (Exception ex)
 99             {
100                 return false;
101             }
102         }
103         #endregion
104 
105         #region 单条覆盖,如果不存在插入,如果存在覆盖
106         /// <summary>
107         /// 单条覆盖,如果不存在插入,如果存在覆盖
108         /// </summary>
109         /// <typeparam name="T"></typeparam>
110         /// <param name="t"></param>
111         public bool Save(T t)
112         {
113             try
114             {
115                 var database = server.GetDatabase(databaseName);   //mongodb中的数据库
116 
117                 var collection = database.GetCollection<T>(tableName);
118                 var result = collection.Save(t);
119                 return result.DocumentsAffected > 0;
120             }
121             catch (Exception ex)
122             {
123                 return false;
124             }
125         }
126         #endregion
127 
128         #region 批量插入
129         /// <summary>
130         /// 批量插入
131         /// </summary>
132         /// <typeparam name="T"></typeparam>
133         /// <param name="t"></param>
134         public bool Insert(IEnumerable<T> t)
135         {
136             try
137             {
138                 var database = server.GetDatabase(databaseName);   //mongodb中的数据库
139 
140                 var collection = database.GetCollection<T>(tableName);
141 
142                 collection.InsertBatch(t);
143 
144                 return true;
145             }
146             catch (Exception ex)
147             {
148                 return false;
149             }
150         }
151         #endregion
152 
153         #region 批量查询
154 
155         public List<T> Search(Expression<Func<T, bool>> func, bool forcemaster = false)
156         {
157             var list = new List<T>();
158 
159             try
160             {
161                 //是否强制使用 “主服务器”
162                 if (forcemaster)
163                 {
164                     var database = server.GetDatabase(databaseName);   //mongodb中的数据库
165 
166                     var collection = database.GetCollection<T>(tableName);
167                     list = collection.Find(Query<T>.Where(func)).ToList();
168                 }
169                 else
170                 {
171                     var database = server.GetDatabase(databaseName);    //mongodb中的数据库
172 
173                     var collection = database.GetCollection<T>(tableName);
174 
175                     list = collection.Find(Query<T>.Where(func)).ToList();
176                 }
177             }
178             catch (Exception ex)
179             {
180                 throw;
181             }
182 
183             return list;
184         }
185 
186         #endregion
187 
188         #region 单条查询
189         /// <summary>
190         /// 单条查询
191         /// </summary>
192         public T SearchOne(Expression<Func<T, bool>> func, bool forcemaster = false)
193         {
194             T t = default(T);
195 
196             try
197             {
198                 if (forcemaster)
199                 {
200                     var database = server.GetDatabase(databaseName);   //mongodb中的数据库
201 
202                     var collection = database.GetCollection<T>(tableName);
203 
204                     t = collection.FindOne(Query<T>.Where(func));
205                 }
206                 else
207                 {
208                     var database = server.GetDatabase(databaseName);   //mongodb中的数据库
209 
210                     var collection = database.GetCollection<T>(tableName);
211 
212                     t = collection.FindOne(Query<T>.Where(func));
213                 }
214 
215                 return t;
216             }
217             catch (Exception ex)
218             {
219                 return t;
220             }
221         }
222         #endregion
223 
224         /// <summary>
225         /// 查询所有数据
226         /// </summary>
227         /// <returns></returns>
228         public List<T> SearchAll()
229         {
230             var list = new List<T>();
231 
232             try
233             {
234                 var database = server.GetDatabase(databaseName);    //mongodb中的数据库
235 
236                 var collection = database.GetCollection<T>(tableName);
237 
238                 list = collection.FindAll().ToList();
239 
240                 return list;
241             }
242             catch (Exception ex)
243             {
244                 return list;
245             }
246         }
247     }
248 }
复制代码

 

四:测试一下

1. 首先向mongodb中插入一条记录,dbname=mydb, tablename=test,插入后我们用mongodUVE看一下数据:

复制代码
 1 namespace ConsoleApplication2
 2 {
 3     class Program
 4     {
 5         static void Main(string[] args)
 6         {
 7             MongoDBHelper<MongodbCustomerModel> helper = new MongoDBHelper<MongodbCustomerModel>("mydb", "test");
 8 
 9             helper.Save(new MongodbCustomerModel()
10             {
11                 SendLastTime = DateTime.Now,
12                 ShopID = 1
13             });
14         }
15     }
16 
17     public class MongodbCustomerModel
18     {
19         public ObjectId _id { get; set; }
20 
21         public int ShopID { get; set; }
22 
23         public DateTime SendLastTime { get; set; }
24     }
25 }
复制代码

 

2. 然后我把【27000】 这个primary关闭掉,通过rs.Status看看“主备情况”。

 

3. 接下来,我们继续用mongodbHelper执行一下search,看是否能捞取到数据,如果可以,说明一台机器挂了没关系,这个“主备集群”还是活的。

 

是不是很牛逼的感觉,虽然挂了一台,我的客户端程序还是可以继续从mognodb中获取到刚才插入的数据,好了,大概就说这么多,洗洗睡了,

 

mongoDB操作命令及mongoDB的helper - 三人成虎 - 博客园

mikel阅读(642)

来源: mongoDB操作命令及mongoDB的helper – 三人成虎 – 博客园

此项目已开源,开源地址是:

http://mongodbhelper-csharp.googlecode.com/svn/trunk/

 

mongodb的helper

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MongoDB.Driver;
using MongoDB.Bson;
using MongoDB.Driver.Builders;
namespace MongoDBHelper
{
    /// <summary>
    /// mongodb的封装类。
    /// add by yancong2008@gmail.com 2011.05.14
    /// </summary>
    public sealed class MongoDBHelper
    //public sealed class MongoDBHelper<T>
    //where T :class
    {
        public static readonly string connectionString_Default = System.Configuration.ConfigurationManager.AppSettings["ConnectionString_mongoDB"];
        public static readonly string database_Default = System.Configuration.ConfigurationManager.AppSettings["Database_mongoDB"];
        #region 新增
        public static SafeModeResult InsertOne<T>(string collectionName, T entity)
        {
            return MongoDBHelper.InsertOne<T>(MongoDBHelper.connectionString_Default, MongoDBHelper.database_Default, collectionName, entity);
        }
        public static SafeModeResult InsertOne<T>(string connectionString, string databaseName, string collectionName, T entity)
        {
            SafeModeResult result = new SafeModeResult();
            if (null == entity)
            {
                return null;
            }
            MongoServer server = MongoServer.Create(connectionString);
            //获取数据库或者创建数据库(不存在的话)。
            MongoDatabase database = server.GetDatabase(databaseName);
            using (server.RequestStart(database))//开始连接数据库。
            {
                MongoCollection<BsonDocument> myCollection = database.GetCollection<BsonDocument>(collectionName);
                result = myCollection.Insert(entity);
            }
            return result;
        }
        public static IEnumerable<SafeModeResult> InsertAll<T>(string collectionName, IEnumerable<T> entitys)
        {
            return MongoDBHelper.InsertAll<T>(MongoDBHelper.connectionString_Default, MongoDBHelper.database_Default, collectionName, entitys);
        }
        public static IEnumerable<SafeModeResult> InsertAll<T>(string connectionString, string databaseName, string collectionName, IEnumerable<T> entitys)
        {
            IEnumerable<SafeModeResult> result = null;
            if (null == entitys)
            {
                return null;
            }
            MongoServer server = MongoServer.Create(connectionString);
            //获取数据库或者创建数据库(不存在的话)。
            MongoDatabase database = server.GetDatabase(databaseName);
            using (server.RequestStart(database))//开始连接数据库。
            {
                MongoCollection<BsonDocument> myCollection = database.GetCollection<BsonDocument>(collectionName);
                result = myCollection.InsertBatch(entitys);
            }
            return result;
        }
        #endregion
        #region 修改
        public static SafeModeResult UpdateOne<T>(string collectionName, T entity)
        {
            return MongoDBHelper.UpdateOne<T>(MongoDBHelper.connectionString_Default, MongoDBHelper.database_Default, collectionName, entity);
        }
        public static SafeModeResult UpdateOne<T>(string connectionString, string databaseName, string collectionName, T entity)
        {
            MongoServer server = MongoServer.Create(connectionString);
            //获取数据库或者创建数据库(不存在的话)。
            MongoDatabase database = server.GetDatabase(databaseName);
            SafeModeResult result;
            using (server.RequestStart(database))//开始连接数据库。
            {
                MongoCollection<BsonDocument> myCollection = database.GetCollection<BsonDocument>(collectionName);
                result = myCollection.Save(entity);
            }
            return result;
        }
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="collectionName"></param>
        /// <param name="query">条件查询。 调用示例:Query.Matches("Title", "感冒") 或者 Query.EQ("Title", "感冒") 或者Query.And(Query.Matches("Title", "感冒"),Query.EQ("Author", "yanc")) 等等</param>
        /// <param name="update">更新设置。调用示例:Update.Set("Title", "yanc") 或者 Update.Set("Title", "yanc").Set("Author", "yanc2") 等等</param>
        /// <returns></returns>
        public static SafeModeResult UpdateAll<T>(string collectionName, IMongoQuery query, IMongoUpdate update)
        {
            return MongoDBHelper.UpdateAll<T>(MongoDBHelper.connectionString_Default, MongoDBHelper.database_Default, collectionName, query, update);
        }
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="connectionString"></param>
        /// <param name="databaseName"></param>
        /// <param name="collectionName"></param>
        /// <param name="query">条件查询。 调用示例:Query.Matches("Title", "感冒") 或者 Query.EQ("Title", "感冒") 或者Query.And(Query.Matches("Title", "感冒"),Query.EQ("Author", "yanc")) 等等</param>
        /// <param name="update">更新设置。调用示例:Update.Set("Title", "yanc") 或者 Update.Set("Title", "yanc").Set("Author", "yanc2") 等等</param>
        /// <returns></returns>
        public static SafeModeResult UpdateAll<T>(string connectionString, string databaseName, string collectionName, IMongoQuery query, IMongoUpdate update)
        {
            SafeModeResult result;
            if (null == query || null == update)
            {
                return null;
            }
            MongoServer server = MongoServer.Create(connectionString);
            //获取数据库或者创建数据库(不存在的话)。
            MongoDatabase database = server.GetDatabase(databaseName);
            using (server.RequestStart(database))//开始连接数据库。
            {
                MongoCollection<BsonDocument> myCollection = database.GetCollection<BsonDocument>(collectionName);
                result = myCollection.Update(query, update, UpdateFlags.Multi);
            }
            return result;
        }
        #endregion
        #region 删除
        public static SafeModeResult Delete(string collectionName, string _id)
        {
            return MongoDBHelper.Delete(MongoDBHelper.connectionString_Default, MongoDBHelper.database_Default, collectionName, _id);
        }
        public static SafeModeResult Delete(string connectionString, string databaseName, string collectionName, string _id)
        {
            SafeModeResult result;
            ObjectId id;
            if (!ObjectId.TryParse(_id, out id))
            {
                return null;
            }
            MongoServer server = MongoServer.Create(connectionString);
            //获取数据库或者创建数据库(不存在的话)。
            MongoDatabase database = server.GetDatabase(databaseName);
            using (server.RequestStart(database))//开始连接数据库。
            {
                MongoCollection<BsonDocument> myCollection = database.GetCollection<BsonDocument>(collectionName);
                result = myCollection.Remove(Query.EQ("_id", id));
            }
            return result;
        }
        public static SafeModeResult DeleteAll(string collectionName)
        {
            return MongoDBHelper.DeleteAll(MongoDBHelper.connectionString_Default, MongoDBHelper.database_Default, collectionName, null);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="collectionName"></param>
        /// <param name="query">条件查询。 调用示例:Query.Matches("Title", "感冒") 或者 Query.EQ("Title", "感冒") 或者Query.And(Query.Matches("Title", "感冒"),Query.EQ("Author", "yanc")) 等等</param>
        /// <returns></returns>
        public static SafeModeResult DeleteAll(string collectionName, IMongoQuery query)
        {
            return MongoDBHelper.DeleteAll(MongoDBHelper.connectionString_Default, MongoDBHelper.database_Default, collectionName, query);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="connectionString"></param>
        /// <param name="databaseName"></param>
        /// <param name="collectionName"></param>
        /// <param name="query">条件查询。 调用示例:Query.Matches("Title", "感冒") 或者 Query.EQ("Title", "感冒") 或者Query.And(Query.Matches("Title", "感冒"),Query.EQ("Author", "yanc")) 等等</param>
        /// <returns></returns>
        public static SafeModeResult DeleteAll(string connectionString, string databaseName, string collectionName, IMongoQuery query)
        {
            MongoServer server = MongoServer.Create(connectionString);
            //获取数据库或者创建数据库(不存在的话)。
            MongoDatabase database = server.GetDatabase(databaseName);
            SafeModeResult result;
            using (server.RequestStart(database))//开始连接数据库。
            {
                MongoCollection<BsonDocument> myCollection = database.GetCollection<BsonDocument>(collectionName);
                if (null == query)
                {
                    result = myCollection.RemoveAll();
                }
                else
                {
                    result = myCollection.Remove(query);
                }
            }
            return result;
        }
        #endregion
        #region 获取单条信息
        public static T GetOne<T>(string collectionName, string _id)
        {
            return MongoDBHelper.GetOne<T>(MongoDBHelper.connectionString_Default, MongoDBHelper.database_Default, collectionName, _id);
        }
        public static T GetOne<T>(string connectionString, string databaseName, string collectionName, string _id)
        {
            T result = default(T);
            ObjectId id;
            if (!ObjectId.TryParse(_id, out id))
            {
                return default(T);
            }
            MongoServer server = MongoServer.Create(connectionString);
            //获取数据库或者创建数据库(不存在的话)。
            MongoDatabase database = server.GetDatabase(databaseName);
            using (server.RequestStart(database))//开始连接数据库。
            {
                MongoCollection<BsonDocument> myCollection = database.GetCollection<BsonDocument>(collectionName);
                result = myCollection.FindOneAs<T>(Query.EQ("_id", id));
            }
            return result;
        }
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="collectionName"></param>
        /// <param name="query">条件查询。 调用示例:Query.Matches("Title", "感冒") 或者 Query.EQ("Title", "感冒") 或者Query.And(Query.Matches("Title", "感冒"),Query.EQ("Author", "yanc")) 等等</param>
        /// <returns></returns>
        public static T GetOne<T>(string collectionName, IMongoQuery query)
        {
            return GetOne<T>(MongoDBHelper.connectionString_Default, MongoDBHelper.database_Default, collectionName, query);
        }
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="connectionString"></param>
        /// <param name="databaseName"></param>
        /// <param name="collectionName"></param>
        /// <param name="query">条件查询。 调用示例:Query.Matches("Title", "感冒") 或者 Query.EQ("Title", "感冒") 或者Query.And(Query.Matches("Title", "感冒"),Query.EQ("Author", "yanc")) 等等</param>
        /// <returns></returns>
        public static T GetOne<T>(string connectionString, string databaseName, string collectionName, IMongoQuery query)
        {
            MongoServer server = MongoServer.Create(connectionString);
            //获取数据库或者创建数据库(不存在的话)。
            MongoDatabase database = server.GetDatabase(databaseName);
            T result = default(T);
            using (server.RequestStart(database))//开始连接数据库。
            {
                MongoCollection<BsonDocument> myCollection = database.GetCollection<BsonDocument>(collectionName);
                if (null == query)
                {
                    result = myCollection.FindOneAs<T>();
                }
                else
                {
                    result = myCollection.FindOneAs<T>(query);
                }
            }
            return result;
        }
        #endregion
        #region 获取多个
        public static List<T> GetAll<T>(string collectionName)
        {
            return MongoDBHelper.GetAll<T>(MongoDBHelper.connectionString_Default, MongoDBHelper.database_Default, collectionName);
        }
        /// <summary>
        /// 如果不清楚具体的数量,一般不要用这个函数。
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="collectionName"></param>
        /// <returns></returns>
        public static List<T> GetAll<T>(string connectionString, string databaseName, string collectionName)
        {
            MongoServer server = MongoServer.Create(connectionString);
            //获取数据库或者创建数据库(不存在的话)。
            MongoDatabase database = server.GetDatabase(databaseName);
            List<T> result = new List<T>();
            using (server.RequestStart(database))//开始连接数据库。
            {
                MongoCollection<BsonDocument> myCollection = database.GetCollection<BsonDocument>(collectionName);
                foreach (T entity in myCollection.FindAllAs<T>())
                {
                    result.Add(entity);
                }
            }
            return result;
        }
        public static List<T> GetAll<T>(string collectionName, int count)
        {
            return MongoDBHelper.GetAll<T>(collectionName, count, nullnull);
        }
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="collectionName"></param>
        /// <param name="count"></param>
        /// <param name="query">条件查询。 调用示例:Query.Matches("Title", "感冒") 或者 Query.EQ("Title", "感冒") 或者Query.And(Query.Matches("Title", "感冒"),Query.EQ("Author", "yanc")) 等等</param>
        /// <returns></returns>
        public static List<T> GetAll<T>(string collectionName, int count, IMongoQuery query)
        {
            return MongoDBHelper.GetAll<T>(collectionName, count, query, null);
        }
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="collectionName"></param>
        /// <param name="count"></param>
        /// <param name="sortBy">排序用的。调用示例:SortBy.Descending("Title") 或者 SortBy.Descending("Title").Ascending("Author")等等</param>
        /// <returns></returns>
        public static List<T> GetAll<T>(string collectionName, int count, IMongoSortBy sortBy)
        {
            return MongoDBHelper.GetAll<T>(collectionName, count, null, sortBy);
        }
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="collectionName"></param>
        /// <param name="count"></param>
        /// <param name="query">条件查询。 调用示例:Query.Matches("Title", "感冒") 或者 Query.EQ("Title", "感冒") 或者Query.And(Query.Matches("Title", "感冒"),Query.EQ("Author", "yanc")) 等等</param>
        /// <param name="sortBy">排序用的。调用示例:SortBy.Descending("Title") 或者 SortBy.Descending("Title").Ascending("Author")等等</param>
        /// <param name="fields">只返回所需要的字段的数据。调用示例:"Title" 或者 new string[] { "Title", "Author" }等等</param>
        /// <returns></returns>
        public static List<T> GetAll<T>(string collectionName, int count, IMongoQuery query, IMongoSortBy sortBy, params string[] fields)
        {
            PagerInfo pagerInfo = new PagerInfo();
            pagerInfo.Page = 1;
            pagerInfo.PageSize = count;
            return MongoDBHelper.GetAll<T>(MongoDBHelper.connectionString_Default, MongoDBHelper.database_Default, collectionName, query, pagerInfo, sortBy, fields);
        }
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="collectionName"></param>
        /// <param name="query">条件查询。 调用示例:Query.Matches("Title", "感冒") 或者 Query.EQ("Title", "感冒") 或者Query.And(Query.Matches("Title", "感冒"),Query.EQ("Author", "yanc")) 等等</param>
        /// <param name="pagerInfo"></param>
        /// <returns></returns>
        public static List<T> GetAll<T>(string collectionName, IMongoQuery query, PagerInfo pagerInfo)
        {
            return MongoDBHelper.GetAll<T>(MongoDBHelper.connectionString_Default, MongoDBHelper.database_Default, collectionName, query, pagerInfo, null);
        }
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="collectionName"></param>
        /// <param name="query">条件查询。 调用示例:Query.Matches("Title", "感冒") 或者 Query.EQ("Title", "感冒") 或者Query.And(Query.Matches("Title", "感冒"),Query.EQ("Author", "yanc")) 等等</param>
        /// <param name="pagerInfo"></param>
        /// <param name="sortBy">排序用的。调用示例:SortBy.Descending("Title") 或者 SortBy.Descending("Title").Ascending("Author")等等</param>
        /// <returns></returns>
        public static List<T> GetAll<T>(string collectionName, IMongoQuery query, PagerInfo pagerInfo, IMongoSortBy sortBy)
        {
            return MongoDBHelper.GetAll<T>(MongoDBHelper.connectionString_Default, MongoDBHelper.database_Default, collectionName, query, pagerInfo, sortBy);
        }
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="collectionName"></param>
        /// <param name="query">条件查询。 调用示例:Query.Matches("Title", "感冒") 或者 Query.EQ("Title", "感冒") 或者Query.And(Query.Matches("Title", "感冒"),Query.EQ("Author", "yanc")) 等等</param>
        /// <param name="pagerInfo"></param>
        /// <param name="fields">只返回所需要的字段的数据。调用示例:"Title" 或者 new string[] { "Title", "Author" }等等</param>
        /// <returns></returns>
        public static List<T> GetAll<T>(string collectionName, IMongoQuery query, PagerInfo pagerInfo, params string[] fields)
        {
            return MongoDBHelper.GetAll<T>(MongoDBHelper.connectionString_Default, MongoDBHelper.database_Default, collectionName, query, pagerInfo, null, fields);
        }
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="collectionName"></param>
        /// <param name="query">条件查询。 调用示例:Query.Matches("Title", "感冒") 或者 Query.EQ("Title", "感冒") 或者Query.And(Query.Matches("Title", "感冒"),Query.EQ("Author", "yanc")) 等等</param>
        /// <param name="pagerInfo"></param>
        /// <param name="sortBy">排序用的。调用示例:SortBy.Descending("Title") 或者 SortBy.Descending("Title").Ascending("Author")等等</param>
        /// <param name="fields">只返回所需要的字段的数据。调用示例:"Title" 或者 new string[] { "Title", "Author" }等等</param>
        /// <returns></returns>
        public static List<T> GetAll<T>(string collectionName, IMongoQuery query, PagerInfo pagerInfo, IMongoSortBy sortBy, params string[] fields)
        {
            return MongoDBHelper.GetAll<T>(MongoDBHelper.connectionString_Default, MongoDBHelper.database_Default, collectionName, query, pagerInfo, sortBy, fields);
        }
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="connectionString"></param>
        /// <param name="databaseName"></param>
        /// <param name="collectionName"></param>
        /// <param name="query">条件查询。 调用示例:Query.Matches("Title", "感冒") 或者 Query.EQ("Title", "感冒") 或者Query.And(Query.Matches("Title", "感冒"),Query.EQ("Author", "yanc")) 等等</param>
        /// <param name="pagerInfo"></param>
        /// <param name="sortBy">排序用的。调用示例:SortBy.Descending("Title") 或者 SortBy.Descending("Title").Ascending("Author")等等</param>
        /// <param name="fields">只返回所需要的字段的数据。调用示例:"Title" 或者 new string[] { "Title", "Author" }等等</param>
        /// <returns></returns>
        public static List<T> GetAll<T>(string connectionString, string databaseName, string collectionName, IMongoQuery query, PagerInfo pagerInfo, IMongoSortBy sortBy, params string[] fields)
        {
            MongoServer server = MongoServer.Create(connectionString);
            //获取数据库或者创建数据库(不存在的话)。
            MongoDatabase database = server.GetDatabase(databaseName);
            List<T> result = new List<T>();
            using (server.RequestStart(database))//开始连接数据库。
            {
                MongoCollection<BsonDocument> myCollection = database.GetCollection<BsonDocument>(collectionName);
                MongoCursor<T> myCursor;
                if (null == query)
                {
                    myCursor = myCollection.FindAllAs<T>();
                }
                else
                {
                    myCursor = myCollection.FindAs<T>(query);
                }
                if (null != sortBy)
                {
                    myCursor.SetSortOrder(sortBy);
                }
                if (null != fields)
                {
                    myCursor.SetFields(fields);
                }
                foreach (T entity in myCursor.SetSkip((pagerInfo.Page - 1) * pagerInfo.PageSize).SetLimit(pagerInfo.PageSize))//.SetSkip(100).SetLimit(10)是指读取第一百条后的10条数据。
                {
                    result.Add(entity);
                }
            }
            return result;
        }
        #endregion
        #region 索引
        public static void CreateIndex(string collectionName, params string[] keyNames)
        {
            MongoDBHelper.CreateIndex(MongoDBHelper.connectionString_Default, MongoDBHelper.database_Default, collectionName, keyNames);
        }
        public static void CreateIndex(string connectionString, string databaseName, string collectionName, params string[] keyNames)
        {
            SafeModeResult result = new SafeModeResult();
            if (null == keyNames)
            {
                return;
            }
            MongoServer server = MongoServer.Create(connectionString);
            //获取数据库或者创建数据库(不存在的话)。
            MongoDatabase database = server.GetDatabase(databaseName);
            using (server.RequestStart(database))//开始连接数据库。
            {
                MongoCollection<BsonDocument> myCollection = database.GetCollection<BsonDocument>(collectionName);
                if (!myCollection.IndexExists(keyNames))
                {
                    myCollection.EnsureIndex(keyNames);
                }
            }
        }
        #endregion
    }
}

 

mongoDB操作命令,摘自官方helper

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
help                         show help
show dbs                     show database names
show collections             show collections in current database
show users                   show users in current database
show profile                 show most recent system.profile entries with time >= 1ms
use <db name>                set curent database to <db name>
db.addUser (username, password)
db.removeUser(username)
db.cloneDatabase(fromhost)
db.copyDatabase(fromdb, todb, fromhost)
db.createCollection(name, { size : ..., capped : ..., max : ... } )
db.getName()
db.dropDatabase()
// runs the collstats] command on each collection in the database
db.printCollectionStats()
db.currentOp() displays the current operation in the db
db.killOp() kills the current operation in the db
db.getProfilingLevel()
db.setProfilingLevel(level) 0=off 1=slow 2=all
db.getReplicationInfo()
db.printReplicationInfo()
db.printSlaveReplicationInfo()
db.repairDatabase()
db.version() current version of the server
db.shutdownServer()
db.foo.drop() drop the collection
db.foo.dropIndex(name)
db.foo.dropIndexes()
db.foo.getIndexes()
db.foo.ensureIndex(keypattern,options) - options object has these possible
fields: name, unique, dropDups
db.foo.find( [query] , [fields]) - first parameter is an optional
query filter. second parameter
is optional
set of fields to return.
e.g. db.foo.find(
{ x : 77 } ,
{ name : 1 , x : 1 } )
db.foo.find(...).count()
db.foo.find(...).limit(n)
db.foo.find(...).skip(n)
db.foo.find(...).sort(...)
db.foo.findOne([query])
db.foo.getDB() get DB object associated with collection
db.foo.count()
db.foo.group( { key : ..., initial: ..., reduce : ...[, cond: ...] } )
db.foo.renameCollection( newName ) renames the collection
db.foo.stats()
db.foo.dataSize()
db.foo.storageSize() - includes free space allocated to this collection
db.foo.totalIndexSize() - size in bytes of all the indexes
db.foo.totalSize() - storage allocated for all data and indexes
db.foo.validate() (slow)
db.foo.insert(obj)
db.foo.update(query, object[, upsert_bool])
db.foo.save(obj)
db.foo.remove(query) - remove objects matching query
remove({}) will remove all

C# Mongodb 封装类 - 我很好123 - 博客园

mikel阅读(1235)

来源: C# Mongodb 封装类 – 我很好123 – 博客园

1.  依赖包 MongoDB.Driver; MongoDB.Json; MongoDB.Bson;

2. 上代码

 

复制代码
  1 using MongoDB.Driver;
  2 using System;
  3 using System.Collections.Generic;
  4 using System.Text;
  5 
  6 using System.Linq;
  7 using System.Linq.Expressions;
  8 using System.Reflection;
  9 using MongoDB.Driver.Linq;
 10 
 11 namespace Common
 12 {
 13 
 14 
 15     public class MongodbHelper
 16     {
 17         protected static MongoClient client;
 18 
 19         public MongodbHelper()
 20         {
 21             client = new MongoClient("mongodb://localhost:27017");
 22         }
 23         static MongodbHelper()
 24         {
 25             client = new MongoClient("mongodb://localhost:27017");
 26         }
 27         /// <summary>
 28         /// 获取 Collection 信息
 29         /// </summary>
 30         /// <typeparam name="T">实体类型</typeparam>
 31         /// <param name="collName">Collection 名称</param>
 32         /// <param name="dbName">DBase名称</param>
 33         /// <returns></returns>
 34         public static MyCollection<T> GetCollection<T>(string collName, string dbName)
 35         {
 36             MyCollection<T> mycollection = new MyCollection<T>();
 37             IMongoDatabase database = client.GetDatabase(dbName);
 38             IMongoCollection<T> collection = database.GetCollection<T>(collName);
 39             mycollection.collection = collection;
 40             return mycollection;
 41         }
 42     }
 43 
 44     public class MyCollection<T>
 45     {
 46         public IMongoCollection<T> collection;
 47 
 48         /// <summary>
 49         /// 查询数据 延迟加载 后期可以使用Linq  Lambda处理数据
 50         /// </summary>
 51         /// <returns></returns>
 52         public IMongoQueryable<T> QueryData()
 53         {
 54             var list = collection.AsQueryable<T>();
 55             return list;
 56         }
 57         /// <summary>
 58         /// 查询所有数据
 59         /// </summary>
 60         /// <param name="expression"></param>
 61         /// <returns></returns>
 62         public List<T> QueryData(Expression<Func<T, bool>> expression)
 63         {
 64             var list = collection.AsQueryable().Where(expression);
 65             return list.ToList<T>();
 66         }
 67 
 68         /// <summary>
 69         /// 分页查询
 70         /// </summary>
 71         /// <param name="expressio"></param>
 72         /// <param name="pageInfo"></param>
 73         /// <returns></returns>
 74         public PageInfo<T> QueryData(Expression<Func<T, bool>> expressio, PageInfo<T> pageInfo)
 75         {
 76             List<T> list = null;
 77             pageInfo.Totoal = collection.AsQueryable<T>().Count();
 78             pageInfo.PageNum = (int)Math.Ceiling(pageInfo.Totoal / pageInfo.PageSize * 0.1);
 79             if (pageInfo == null || pageInfo.IsAll == true)
 80                 if (expressio != null)
 81                     list = collection.AsQueryable<T>().Where(expressio).ToList();
 82                 else list = collection.AsQueryable<T>().ToList();
 83             else if (expressio != null)
 84             {
 85                 list = collection.AsQueryable<T>().Where(expressio).Skip(pageInfo.PageSize * (pageInfo.PageIndex - 1)).Take(pageInfo.PageSize).ToList();
 86             }
 87             else
 88             {
 89                 list = collection.AsQueryable<T>().Skip(pageInfo.PageSize * (pageInfo.PageIndex - 1)).Take(pageInfo.PageSize).ToList();
 90             }
 91             pageInfo.Data = list;
 92             return pageInfo;
 93         }
 94 
 95         /// <summary>
 96         /// 新增一条数据(文档)
 97         /// </summary>
 98         /// <param name="ts"></param>
 99         public void AddDoc(T ts)
100         {
101             collection.InsertOne(ts);
102         }
103         /// <summary>
104         /// 批量新增多个文档
105         /// </summary>
106         /// <param name="ts"></param>
107         public void AddDocs(List<T> ts)
108         {
109             collection.InsertMany(ts);
110         }
111         /// <summary>
112         /// 更新文档  不存在就新增
113         /// </summary>
114         /// <param name="filter"></param>
115         /// <param name="t"></param>
116         public void UpdateDoc(Expression<Func<T, bool>> filter, T t)
117         {
118             // FilterDefinition<T> filter = null;
119             //  UpdateDefinition<T> update = Builders<T>.Update.ToBsonDocument();//   null;// Builders<T>.Update.
120             var newData = BuildQueryOption(t);
121             UpdateResult result = collection.UpdateOne(filter, newData, new UpdateOptions { IsUpsert = true });
122         }
123         /// <summary>
124         /// 删除文档   
125         /// </summary>
126         /// <param name="predicate"></param>
127         public void Detele(Expression<Func<T, bool>> predicate)
128         {
129             var result = collection.DeleteMany(predicate);//.ConfigureAwait(false);
130                                                           // return result.DeletedCount;
131         }
132         /// <summary>
133         /// 利用反射创建 更新字段 (这里没有处理空)
134         /// </summary>
135         /// <param name="doc"></param>
136         /// <returns></returns>
137         private UpdateDefinition<T> BuildQueryOption(T doc)
138         {
139             var update = Builders<T>.Update;
140             var updates = new List<UpdateDefinition<T>>();
141 
142             var t = doc.GetType();
143             var proper = t.GetProperties();
144             foreach (PropertyInfo info in proper)
145             {
146                 var value = info.GetValue(doc);
147                 if (value != null)
148                 {
149                     updates.Add(update.Set(info.Name, info.GetValue(doc)));
150                 }
151 
152             }
153             // update.Combine(updates);
154             return update.Combine(updates);
155         }
156     }
157     /// <summary>
158     /// 分页信息
159     /// </summary>
160     /// <typeparam name="T"></typeparam>
161     public class PageInfo<T>
162     {
163         public bool IsAll { get; set; } = false;
164         public int PageSize { get; set; } = 100;
165         public int PageIndex { get; set; } = 1;
166         public long Totoal { get; set; }
167 
168         public int PageNum { get; set; }
169 
170         public List<T> Data { get; set; }
171     }
172 }
复制代码

3. 测试方法

复制代码
using Common;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;

namespace ZhiHuHot
{
    public class TestMongo
    {

        public void GetHot()
        {
            MyCollection<HotInfo> collection = MongodbHelper.GetCollection<HotInfo>("ZhiHuHot", "ZhiHu");

            Expression<Func<HotInfo, bool>> predicate = null;

            predicate = a => a.HotID.Equals(391481443);

            PageInfo<HotInfo> hots = collection.QueryData(null, new PageInfo<HotInfo>());
        }
    }
}
复制代码

 

C#使用MongoDB数据库的帮助类_qq_32733803的博客-CSDN博客

mikel阅读(620)

来源: C#使用MongoDB数据库的帮助类_qq_32733803的博客-CSDN博客

1 添加NUGET包
2 在config中添加
3 创建连接类
 internal static class DbConfigParams
{
private static string _conntionString = ConfigurationManager.AppSettings[“MongoDBConn”];
        /// <summary>
/// 获取 数据库连接串
/// </summary>
public static string ConntionString
{
get { return _conntionString; }
}
        private static string _dbName = ConfigurationManager.AppSettings[“MongoDBName”];
        /// <summary>
/// 获取 数据库名称
/// </summary>
public static string DbName
{
get { return _dbName; }
}
        /// <summary>
/// 获取 数据库连接串+数据库名称
/// </summary>
public static string conString
{
get { return _conntionString + “/” + _dbName; }
}
    }
4 创建帮助类
  /// <summary>
/// MongoDb 数据库操作类
/// </summary>
public class MongoDBHelper<T> where T : BaseEntity
{
/// <summary>
/// 数据库对象
/// </summary>
private IMongoDatabase database;
/// <summary>
/// 连接字符串
/// </summary>
static string _conString = DbConfigParams.conString;
/// <summary>
/// 构造函数
/// </summary>
/// <param name=”conString”>连接字符串</param>
public MongoDBHelper()
{
var url = new MongoUrl(_conString);
MongoClientSettings mcs = MongoClientSettings.FromUrl(url);
mcs.MaxConnectionLifeTime = TimeSpan.FromMilliseconds(1000);
var client = new MongoClient(mcs);
this.database = client.GetDatabase(url.DatabaseName);
}
/// <summary>
/// 创建集合对象
/// </summary>
/// <param name=”collName”>集合名称</param>
///<returns>集合对象</returns>
private IMongoCollection<T> GetColletion(String collName)
{
return database.GetCollection<T>(collName);
}
        #region 增加
/// <summary>
/// 插入对象
/// </summary>
/// <param name=”collName”>集合名称</param>
/// <param name=”t”>插入的对象</param>
public void Insert(String collName, T t)
{
var coll = GetColletion(collName);
coll.InsertOne(t);
}
/// <summary>
/// 批量插入
/// </summary>
/// <param name=”collName”>集合名称</param>
/// <param name=”ts”>要插入的对象集合</param>
public void InsertBath(String collName, IEnumerable<T> ts)
{
var coll = GetColletion(collName);
coll.InsertMany(ts);
}
#endregion
        #region 删除
/// <summary>
/// 按BsonDocument条件删除
/// </summary>
/// <param name=”collName”>集合名称</param>
/// <param name=”document”>文档</param>
/// <returns></returns>
//public Int64 Delete(String collName, QueryDocument document)
//{
//    var coll = GetColletion(collName);
//    var result = coll.DeleteMany(document);
//    return result.DeletedCount;
//}
/// <summary>
/// 按json字符串删除
/// </summary>
/// <param name=”collName”>集合名称</param>
/// <param name=”json”>json字符串</param>
/// <returns></returns>
public Int64 Delete(String collName, String json)
{
var coll = GetColletion(collName);
var result = coll.DeleteMany(json);
return result.DeletedCount;
}
/// <summary>
/// 按条件表达式删除
/// </summary>
/// <param name=”collName”>集合名称</param>
/// <param name=”predicate”>条件表达式</param>
/// <returns></returns>
//public Int64 Delete(String collName, Expression<Func<T, Boolean>> predicate)
//{
//    var coll = GetColletion(collName);
//    var result = coll.DeleteMany(predicate);
//    return result.DeletedCount;
//}
/// <summary>
/// 按检索条件删除
/// 建议用Builders<T>构建复杂的查询条件
/// </summary>
/// <param name=”collName”>集合名称</param>
/// <param name=”filter”>条件</param>
/// <returns></returns>
public Int64 Delete(String collName, FilterDefinition<T> filter)
{
var coll = GetColletion(collName);
var result = coll.DeleteMany(filter);
return result.DeletedCount;
}
        #endregion
        #region 修改
/// <summary>
/// 修改文档
/// </summary>
/// <param name=”collName”>集合名称</param>
/// <param name=”filter”>修改条件</param>
/// <param name=”update”>修改结果</param>
/// <param name=”upsert”>是否插入新文档(filter条件满足就更新,否则插入新文档)</param>
/// <returns></returns>
public Int64 Update(String collName, Expression<Func<T, Boolean>> filter, UpdateDefinition<T> update, Boolean upsert = false)
{
var coll = GetColletion(collName);
var result = coll.UpdateMany(filter, update, new UpdateOptions { IsUpsert = upsert });
return result.ModifiedCount;
}
/ <summary>
/ 用新对象替换新文档-更新批量
/ </summary>
/ <param name=”collName”>集合名称</param>
/ <param name=”filter”>修改条件</param>
/ <param name=”t”>新对象</param>
/ <param name=”upsert”>是否插入新文档(filter条件满足就更新,否则true插入新文档)</param>
/ <returns>修改影响文档数</returns>
//public Int64 UpdateT(String collName, FilterDefinition<T> filter, T t, Boolean upsert = false)
//{
//    var coll = GetColletion(collName);
//    BsonDocument document = t.ToBsonDocument<T>();
//    document.Remove(“_id”);
//    UpdateDocument update = new UpdateDocument(“$set”, document);
//    var result = coll.UpdateMany(filter, update, new UpdateOptions { IsUpsert = upsert });
//    return result.ModifiedCount;
//}
/ <summary>
/ 用新对象替换新文档-更新单个
/ </summary>
/ <param name=”collName”>集合名称</param>
/ <param name=”filter”>修改条件</param>
/ <param name=”t”>新对象</param>
/ <param name=”upsert”>是否插入新文档(filter条件满足就更新,否则true插入新文档)</param>
/ <returns>修改影响文档数</returns>
//public Int64 UpdateOne(String collName, FilterDefinition<T> filter, T t, Boolean upsert = false)
//{
//    var coll = GetColletion(collName);
//    BsonDocument document = t.ToBsonDocument<T>();
//    document.Remove(“_id”);
//    UpdateDocument update = new UpdateDocument(“$set”, document);
//    var result = coll.UpdateOne(filter, update, new UpdateOptions { IsUpsert = upsert });
//    return result.ModifiedCount;
//}
#endregion
        #region 查询
        /// <summary>
/// 查询,复杂查询直接用Linq处理
/// </summary>
/// <param name=”collName”>集合名称</param>
/// <returns>要查询的对象</returns>
private IQueryable<T> GetQueryable(String collName)
{
var coll = GetColletion(collName);
return coll.AsQueryable<T>();
}
/// <summary>
/// 根据条件表达式返回可查询的记录源
/// </summary>
/// <param name=”query”>查询条件</param>
/// <param name=”sortPropertyName”>排序表达式</param>
/// <param name=”isDescending”>如果为true则为降序,否则为升序</param>
/// <returns></returns>
private IFindFluent<T, T> GetQueryable(String collName, FilterDefinition<T> query, string sortPropertyName, bool isDescending = true)
{
IMongoCollection<T> collection = GetColletion(collName);
IFindFluent<T, T> queryable = collection.Find(query);
var sort = isDescending ? Builders<T>.Sort.Descending(sortPropertyName) : Builders<T>.Sort.Ascending(sortPropertyName);
return queryable.Sort(sort);
}
/// <summary>
/// 根据条件表达式返回可查询的记录源
/// </summary>
/// <param name=”match”>查询条件</param>
/// <param name=”orderByProperty”>排序表达式</param>
/// <param name=”isDescending”>如果为true则为降序,否则为升序</param>
/// <returns></returns>
private IQueryable<T> GetQueryable<TKey>(String collName, Expression<Func<T, bool>> match, Expression<Func<T, TKey>> orderByProperty, bool isDescending = true)
{
IMongoCollection<T> collection = GetColletion(collName);
IQueryable<T> query = collection.AsQueryable();
            if (match != null)
{
query = query.Where(match);
}
            if (orderByProperty != null)
{
query = isDescending ? query.OrderByDescending(orderByProperty) : query.OrderBy(orderByProperty);
}
else
{
// query = query.OrderBy(sortPropertyName, isDescending);
}
return query;
}
/// <summary>
/// 根据条件查询数据库,并返回对象集合
/// </summary>
/// <param name=”match”>条件表达式</param>
/// <param name=”sortPropertyName”>排序字段</param>
/// <param name=”isDescending”>如果为true则为降序,否则为升序</param>
/// <returns></returns>
public IList<T> Find(String collName, Expression<Func<T, bool>> match, string sortPropertyName, bool isDescending = true)
{
return GetQueryable(collName, match, sortPropertyName, isDescending).ToList();
}
/// <summary>
/// 根据条件查询数据库,并返回对象集合
/// </summary>
/// <param name=”query”>条件表达式</param>
/// <param name=”sortPropertyName”>排序字段</param>
/// <param name=”isDescending”>如果为true则为降序,否则为升序</param>
/// <returns></returns>
public IList<T> Find(String collName, FilterDefinition<T> query, string sortPropertyName, bool isDescending = true)
{
return GetQueryable(collName, query, sortPropertyName, isDescending).ToList();
}
/// <summary>
/// 根据条件查询数据库,并返回对象集合
/// </summary>
/// <param name=”match”>条件表达式</param>
/// <param name=”orderByProperty”>排序表达式</param>
/// <param name=”isDescending”>如果为true则为降序,否则为升序</param>
/// <returns></returns>
public IList<T> Find<TKey>(String collName, Expression<Func<T, bool>> match, Expression<Func<T, TKey>> orderByProperty, bool isDescending = true)
{
return GetQueryable<TKey>(collName, match, orderByProperty, isDescending).ToList();
}
/// <summary>
/// 根据条件查询数据库,如果存在返回第一个对象
/// </summary>
/// <param name=”filter”>条件表达式</param>
/// <returns>存在则返回指定的第一个对象,否则返回默认值</returns>
public T FindSingle(String collName, FilterDefinition<T> filter)
{
var coll = GetColletion(collName);
return coll.Find(filter).FirstOrDefault();
}
/ <summary>
/ 根据条件查询数据库,并返回对象集合(用于分页数据显示)
/ </summary>
/ <param name=”query”>条件表达式</param>
/ <param name=”info”>分页实体</param>
/ <returns>指定对象的集合</returns>
//public IList<T> FindWithPager(string collName, FilterDefinition<T> query, PagerInfo info, string orderByProperty, bool isDescending = true)
//{
//    int pageindex = (info.CurrenetPageIndex < 1) ? 1 : info.CurrenetPageIndex;
//    int pageSize = (info.PageSize <= 0) ? 20 : info.PageSize;
//    int excludedRows = (pageindex – 1) * pageSize;
//    var find = GetQueryable(collName, query, orderByProperty, isDescending);
//    info.RecordCount = (int)find.Count();
//    return find.Skip(excludedRows).Limit(pageSize).ToList();
//}
/// <summary>
/// 根据条件查询数据库,并返回对象集合(用于分页数据显示)
/// </summary>
/// <param name=”match”>条件表达式</param>
/// <param name=”info”>分页实体</param>
/// <returns>指定对象的集合</returns>
//public IList<T> FindWithPager(String collName, Expression<Func<T, bool>> match, PagerInfo info, string orderByProperty, bool isDescending = true)
//{
//    int pageindex = (info.CurrenetPageIndex < 1) ? 1 : info.CurrenetPageIndex;
//    int pageSize = (info.PageSize <= 0) ? 20 : info.PageSize;
        //    int excludedRows = (pageindex – 1) * pageSize;
        //    IQueryable<T> query = GetQueryable(collName,match, orderByProperty, isDescending);
//    info.RecordCount = query.Count();
        //    return query.Skip(excludedRows).Take(pageSize).ToList();
//}
#endregion
}
    /// <summary>
/// 实体基类,方便生成_id
/// </summary>
public class BaseEntity
{
[BsonRepresentation(BsonType.ObjectId)]
public String Id { get; set; }
/// <summary>
/// 给对象初值
/// </summary>
public BaseEntity()
{
this.Id = ObjectId.GenerateNewId().ToString();
}
}

Challenges when upgrading from meteor 1.6 to meteor 1.7 | by Michael Lazarski | Medium

mikel阅读(517)

来源: Challenges when upgrading from meteor 1.6 to meteor 1.7 | by Michael Lazarski | Medium

Error 1: `Identifier ‘InheritPrototype’ has already been declared`

W20180702-12:59:21.872(2)? (STDERR) let InheritPrototype;
W20180702-12:59:21.872(2)? (STDERR)     ^
W20180702-12:59:21.872(2)? (STDERR) 
W20180702-12:59:21.873(2)? (STDERR) SyntaxError: Identifier 'InheritPrototype' has already been declared
W20180702-12:59:21.873(2)? (STDERR)     at createScript (vm.js:80:10)
W20180702-12:59:21.873(2)? (STDERR)     at Object.runInThisContext (vm.js:139:10)

This is one has todo with meteor packages and api modules.

You have the following in a meteor package:

api.addFiles('lib/main.js', [ 'client', 'server' ]);api.mainModule('lib/main.js', ['client', 'server']);

This will produce the error message because the same file is loaded twice.

Solution:

Most often you can just remove the api.addFiles line and everything should be okay but you have to make sure that this is really the case. Also don’t forget to bump the versionFrom to `api.versionsFrom(‘1.7’);` and your package version.

Error 2: Broken persistent session package

TypeError: Cannot read property 'apply' of undefined
 at ReactiveDict.PersistentSession.old_get (u2622_persistent-session.js?hash=57db38c11edeebc31dce68f5b5be8581c20a2286:241)
 at ReactiveDict._psGet [as get] (u2622_persistent-session.js?hash=57db38c11edeebc31dce68f5b5be8581c20a2286:244)
 at blaze.js?hash=a1ff2d6d5ecd59ee11e2ba260b8650a9d1140f59:1934
 at Function.Template._withTemplateInstanceFunc (blaze.js?hash=a1ff2d6d5ecd59ee11e2ba260b8650a9d1140f59:3744)
 at blaze.js?hash=a1ff2d6d5ecd59ee11e2ba260b8650a9d1140f59:1932
 at Object.Blaze._withCurrentView (blaze.js?hash=a1ff2d6d5ecd59ee11e2ba260b8650a9d1140f59:2271)
 at viewAutorun (blaze.js?hash=a1ff2d6d5ecd59ee11e2ba260b8650a9d1140f59:1931)
 at Computation._compute (tracker.js:308)
 at new Computation (tracker.js:206)

This will happen when you use the u2622:persistent-session .

Solution:

meteor remove u2622:persistent-session
meteor add cultofcoders:persistent-session

Pretty easy 😉

Error 3: Missing dependencies in package.js

So it looks that with 1.7 meteor is even more strikt when it comes to package dependencies. When for example your missing _ you will no get this error:

W20180702-14:05:42.877(2)? (STDERR) TypeError: _.each is not a function

This can also happen after the meteor build was successful and when your loading the page or running functions. So i would suggest that you to a full app test after upgrading.

Solution:

You have to add _ to your package or what ever dependency is missing.

api.use([
    'ecmascript',
    'underscore',
]);

在.NET Core中使用MongoDB明细教程(1):驱动基础及文档插入 - 依乐祝 - 博客园

mikel阅读(598)

来源: 在.NET Core中使用MongoDB明细教程(1):驱动基础及文档插入 – 依乐祝 – 博客园

MongoDB,被归类为NoSQL数据库,是一个以类JSON格式存储数据的面向文档的数据库系统.MongoDB在底层以名为bson的二进制编码格式表示JSON文档,MongoDB bson实现是轻量级、快速和高度可遍历的。这意味着MongoDB为用户提供了JSON文档的易用性和灵活性,以及轻量级二进制格式的速度和丰富性。其实在我看来在很多场景中MongoDb都可以取代关系型数据库。

作者:依乐祝
原文地址:https://www.cnblogs.com/yilezhu/p/13493195.html

在本教程系列中,我将向您展示如何使用.NET驱动程序提供的CRUD函数在.NET应用程序中使用MongoDB。MongoDB驱动允许您使用来自不同编程语言的MongoDB。在本系列教程中,我们将使用C#驱动程序.

准备工作

在开始之前,我们需要打开VisualStudio并创建一个新项目。我将在本教程中使用一个控制台项目。为了演示我们需要安装对应的NuGet包。这里我们需要三个NuGet包,即:

  1. MongoDB.Bson独立的BSON库,它处理POCOS到BSON类型的转换(这是MongoDB的文件格式),反之亦然。
  2. MongoDB.Driver.Core:–它本身就是一个驱动程序,具有驱动程序的核心组件(如如何连接到mongod实例,连接池),用于从.net到MongoDB的通信,并且它依赖于MongoDB.Bson.
  3. MongoDB.Driver*依赖于Driver.Core这反过来又依赖于MongoDB.Bson。它更容易在核心组件驱动程序上使用api,并具有异步方法,并支持Linq.

运行以下命令,会同时安装上面三个包:

Install-Package MongoDB.Driver

访问数据库

若要连接到数据库,请使用MongoClient类访问MongoDB实例,并通过它选择要使用的数据库。这个类有四个构造函数。

  • 默认情况下,连接到端口27017上的实例的无参数结构器:
var client = new MongoClient();
  • 接受连接字符串:
var connectionString = "mongodb://localhost:27017";
var client = new MongoClient(connectionString);
  • 接受一个MongoUrl的实例,而MongoUrl跟使用connectionstring构造函数很类似,您可以通过使用默认构造函数来创建此类实例:
var client = new MongoClient(new MongoUrl("mongodb://localhost:27017"));

.或者使用静态的Create方法:

var client = new MongoClient(MongoUrl.Create("mongodb://localhost:27017"));
  • 最后一个是接受一个MongoClientSettings的构造函数,这里你可以设置很多东西,比如凭据、连接生存期和超时时间等等。下面是两个例子:
var settings1 = MongoClientSettings
        .FromUrl(MongoUrl.Create("mongodb://localhost:27017"));

var settings2 = new MongoClientSettings
          {
          Server = new MongoServerAddress("localhost", 27017),
          UseSsl = false
          };

var client1 = new MongoClient(settings1);
var client2 = new MongoClient(settings2);

通常,你只需要使用包含一个connectionString参数的构造函数就可以了,我们将在本教程中使用此构造函数。代码如下所示:

using MongoDB.Driver;
using System;
namespace MongoDBDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Test();
            Console.ReadLine();
        }

        static void Test()
        {
            var connectionString = "mongodb://localhost:27017";

            var client = new MongoClient(connectionString);
        }
    }
}

使用MongoClient实例,我们可以做很多事情,如删除数据库、获取数据库或检索服务器上的数据库名称列表等。这里没有一个用于创建数据库方法,因为一旦您选择一个数据库并将数据插入其中,它将自动创建数据库。

这里我们使用的是GetDatabase方法,它将自动为我们创建一个数据库。如下所示获取一个名为bookstore 的数据库:

IMongoDatabase db = client.GetDatabase("bookstore");

这个GetDatabase方法返回一个对象,该对象是数据库的表示形式,我们可以从该对象访问不同的集合并操作数据库。这个MongoClient对象是线程安全的,因此您可以将其放在静态字段中,使其成为可以通过DI容器随时获得的Singleton对象,或者使用相同的连接设置实例化一个新的字段(下面将使用相同的连接池);通过这个对象,您可以选择您想要使用的任何数据库。

使用数据库对象,可以从数据库创建、重命名、检索或获取集合列表。文档存储在集合中,如果你对SQL比较熟悉的话,可以将集合视为表,将文档视为表中的记录。

创建一个集合

若要创建集合,我们将使用 IMongoDatabase对象的CreateCollection 或CreateCollection Async方法来进行 。该方法接受三个参数(最后两个参数是可选的):

  1. 集合的名称。
  2. 创建集合的选项
  3. 取消令牌
 void CreateCollection(
                string name,
                CreateCollectionOptions options = null,
                CancellationToken cancellationToken = default);

Task CreateCollectionAsync(
                string name, 
                CreateCollectionOptions options = null, 
                CancellationToken cancellationToken = default);

这个CreateCollectionOptions指定集合的特殊设置,例如它应该包含的最大文档数。下面是一个例子:

 IMongoDatabase database = client.GetDatabase("bookstore");
 await database.CreateCollectionAsync("books", new CreateCollectionOptions
            {
                Capped=true,
                MaxDocuments=100,
            });

大多数情况下,我们只需要创建一个集合,并使用默认的创建设置,因此我们只需要传递一个collection的名称即可。

await database.CreateCollectionAsync("books");

创建集合的另一种方法是使用GetCollection它接受集合的名称和集合设置选项作为参数。使用此方法,即使不存在该名称的集合,一旦创建文档,它也会在此之前创建该集合。这通常是您想要的方式,因此这里建议只在你需要创建一个有上限的集合时才使用CREATE进行集合的创建。

Capped集合是一个固定大小的集合,当它达到最大值时,它会自动覆盖其最旧的条目。GetCollection方法是泛型的,在调用此方法时需要指定文档类型。该类型表示要处理的对象/文档的类型。它可以被强类型化为我们定义的任何类,或者使用BsonDocument类型表示一个允许我们处理集合中任何文档形状的动态架构。

获取一个集合

在讨论了创建集合之后,还需要一个额外的步骤来检查集合是否存在,创建它,然后将文档添加到集合中。如果集合不存在,GetCollection会自动创建一个集合,并将文档添加到该集合中。因此,即使有一个CreateCollection,我们通常还是希望使用GetCollection。就像数据库一样,集合也是线程安全的,并且创建起来非常j简单。为了获得一个集合,我们调用GetCollection方法来指定文档类型

 static async Task TestAsync()
        {
            var connectionString = "mongodb://localhost:27017";
            var client = new MongoClient(connectionString);
            IMongoDatabase database = client.GetDatabase("bookstore");
            IMongoCollection<BsonDocument> collection = database.GetCollection<BsonDocument>("books");
        }

BsonDocument是来自MongoDB.Bson包的类型,它表示BSON文档,使用这种类型,我们可以处理来自数据库的任何形状的数据。这包含了所有基本BSON类型和其他一些用于使用BSON的方法。

在这个包中,我们有表示BSON类型的类,以及如何在.NET类型和BsonValue之间映射。下面简单列举一些:

  • 我们已经讨论过的BsonDocument类型
  • 表示BSON元素的BsonElement
  • BsonValue是各种子类使用的抽象基类,如BsonString、BsonInt 32等。

这个BsonDocument是字符串到bson值的字典,因此我们可以像初始化字典一样来进行初始化:

 var document = new BsonDocument
            {
                  {"bookname", BsonValue.Create(".net core3.1 with mongodb")},
                  {"description", new BsonString("这是一本关于在.net core3.1中使用mongodb进行开发的教程")},
                  {"tags", new BsonArray(new[] {".net core", "mongodb"}) },
                  {"remark", "C#是世界上最好的语言" },
                  {"publishyear", 2020 }
            };

.或者使用Add方法,该方法具有多个重载:

 var document2 = new BsonDocument();
            document2.Add("bookname", ".net core3.1 with mongodb2");
            document2.Add("description", "这是一本关于在.net core3.1中使用mongodb进行开发的教程2");
            document2.Add("tags", new BsonArray(new[] { ".net core", "mongodb" }));
            document2.Add("remark", "C#是世界上最好的语言");
            document2.Add("publishyear", 2020);

.或者使用索引器:

var document3 = new BsonDocument();
            document3["bookname"] = ".net core3.1 with mongodb3";
            document3["description"] = "这是一本关于在.net core3.1中使用mongodb进行开发的教程3";
            document3["tags"] = new BsonArray(new[] { ".net core", "mongodb" });
            document3["remark"] = "C#是世界上最好的语言";
            document3["publishyear"] = 2020;

创建/插入文档

文档存储在集合中,在查看了创建和获取集合之后,我们将继续在集合中插入新文档。Mongo集合实例提供了一次插入单个文档和一次插入多个文档的方法。

接下来让我们一步一步来进行实现吧:

  • 获取一个IMongocollection类型的对象,该对象表示我们要使用的集合:
 IMongoCollection<BsonDocument> collection = database.GetCollection<BsonDocument>("books");
  • 然后创建我们想要插入的文档:
 var document = new BsonDocument
            {
                  {"bookname", BsonValue.Create(".net core3.1 with mongodb")},
                  {"description", new BsonString("这是一本关于在.net core3.1中使用mongodb进行开发的教程")},
                  {"tags", new BsonArray(new[] {".net core", "mongodb"}) },
                  {"remark", "C#是世界上最好的语言" },
                  {"publishyear", 2020 }
            };
  • 最后插入该文件:
await collection.InsertOneAsync(document);

要想看到这个效果,让我们开始一个mongod实例,并从控制台监视事件的同时运行以下完整代码:

class Program
    {
        static async Task Main(string[] args)
        {
            await TestAsync();
            Console.ReadLine();
        }

        /// <summary>
        /// 测试代码
        /// </summary>
        /// <returns></returns>
        static async Task TestAsync()
        {
            var connectionString = "mongodb://localhost:27017";

            var client = new MongoClient(connectionString);
            IMongoDatabase database = client.GetDatabase("bookstore");
            IMongoCollection<BsonDocument> collection = database.GetCollection<BsonDocument>("books");
            var document = new BsonDocument
            {
                  {"bookname", BsonValue.Create(".net core3.1 with mongodb")},
                  {"description", new BsonString("这是一本关于在.net core3.1中使用mongodb进行开发的教程")},
                  {"tags", new BsonArray(new[] {".net core", "mongodb"}) },
                  {"remark", "C#是世界上最好的语言" },
                  {"publishyear", 2020 }
            };
            await collection.InsertOneAsync(document);
        }
    }

…启动你的mongo服务并运行程序,看到如下所示的数据:

这里的InsertOneAsync方法还有一个同步的版本

collection.InsertOne(document);

我们还可以使用InsertManyInsertManyAsync方法进行批量插入。假设我们图书馆又来了三本新书,我们可以使用这个方法同时插入所有的内容,并且它们将被插入到一个批中(假设您使用的是MongoDB2.6或更高版本)。要查看此操作,我们将继续更新代码并运行应用程序:

class Program
    {
        static async Task Main(string[] args)
        {
            await TestAsync();
            Console.ReadLine();
        }

        /// <summary>
        /// 测试代码
        /// </summary>
        /// <returns></returns>
        static async Task TestAsync()
        {
            var connectionString = "mongodb://localhost:27017";
            var client = new MongoClient(connectionString);
            IMongoDatabase database = client.GetDatabase("bookstore");
            IMongoCollection<BsonDocument> collection = database.GetCollection<BsonDocument>("books");
            await collection.InsertManyAsync(GetBooks());
          
        }

        static IEnumerable<BsonDocument> GetBooks() => new List<BsonDocument> {
            new BsonDocument
            {
                  {"bookname", BsonValue.Create(".net core3.1 with mongodb1")},
                  {"description", new BsonString("这是一本关于在.net core3.1中使用mongodb进行开发的教程1")},
                  {"tags", new BsonArray(new[] {".net core", "mongodb"}) },
                  {"remark", "C#是世界上最好的语言" },
                  {"publishyear", 2020 }
            },
            new BsonDocument
            {
                  {"bookname", BsonValue.Create(".net core3.1 with mongodb2")},
                  {"description", new BsonString("这是一本关于在.net core3.1中使用mongodb进行开发的教程2")},
                  {"tags", new BsonArray(new[] {".net core", "mongodb"}) },
                  {"remark", "C#是世界上最好的语言" },
                  {"publishyear", 2020 }
            },
            new BsonDocument
            {
                  {"bookname", BsonValue.Create(".net core3.1 with mongodb2")},
                  {"description", new BsonString("这是一本关于在.net core3.1中使用mongodb进行开发的教程2")},
                  {"tags", new BsonArray(new[] {".net core", "mongodb"}) },
                  {"remark", "C#是世界上最好的语言" },
                  {"publishyear", 2020 }
            },
        };
    }

这时候我们再进行夏查询,看到所有数据都入库了
1597204359324.png

除了使用BsonDocument,我们通常预先知道我们想要处理的是什么样的数据,并且我们可以为它们创建自定义的.NET类。遵循我们使用books集合的事例,让我们创建一个Book类并插入使用此类表示的新书籍:

internal class Book
{
        public string BookName { get; set; }
        public string Description { get; set; }
        public IEnumerable<string> Tags { get; set; }
        public string Remark { get; set; }
        public int PublishYear { get; set; }
}
class Program
    {
        static async Task Main(string[] args)
        {
            await TestAsync();
            Console.ReadLine();
        }

        /// <summary>
        /// 测试代码
        /// </summary>
        /// <returns></returns>
        static async Task TestAsync()
        {
            var connectionString = "mongodb://localhost:27017";
            var client = new MongoClient(connectionString);
            IMongoDatabase database = client.GetDatabase("bookstore");
            IMongoCollection<Book> collection = database.GetCollection<Book>("books");
            await collection.InsertManyAsync(GetBooks());
        }

        static IEnumerable<Book> GetBooks() => new List<Book> { 
            new Book
            {
                BookName=".net core3.1 with mongodb21",
                Description="这是一本关于在.net core3.1中使用mongodb进行开发的教程21",
                Tags=new List<string>{ ".net core", "mongodb"},
                Remark="C#是世界上最好的语言",
                PublishYear=2020,
            },
            new Book
            {
                BookName=".net core3.1 with mongodb22",
                Description="这是一本关于在.net core3.1中使用mongodb进行开发的教程22",
                Tags=new List<string>{ ".net core", "mongodb"},
                Remark="C#是世界上最好的语言",
                PublishYear=2020,
            },
            new Book
            {
                BookName=".net core3.1 with mongodb23",
                Description="这是一本关于在.net core3.1中使用mongodb进行开发的教程23",
                Tags=new List<string>{ ".net core", "mongodb"},
                Remark="C#是世界上最好的语言",
                PublishYear=2020,
            },
        };
    }

使用上面的代码,我们可以将集合的文档类型更改为新类,并调用InsertManyAsync方法。运行下程序,然后查询下集合数据如下所示:

总结

通过上面的示例代码的讲解,你应该对如何通过MongoDB .NET 驱动程序来操作MongoDB集合跟文档有所了解了,并且你也应该知道如何进行文档的插入,在下一篇文章中,我将介绍如何对文档进行检索以及为此构建的各种filter及linq查询技巧,有兴趣的可以关注下我的公众号“DotNetCore实战”第一时间进行更新!

参考资料:https://www.codementor.io/@pmbanugo/working-with-mongodb-in-net-1-basics-g4frivcvz

MongoDB C# 驱动教程 - 微笑点燃希望 - 博客园

mikel阅读(907)

来源: MongoDB C# 驱动教程 – 微笑点燃希望 – 博客园

C# 驱动版本 v1.6.x

本教程基于C#驱动 v1.6.x 。 Api 文档见此处: http://api.mongodb.org/csharp/current/.

简介

本教程介绍由10gen支持的,用于MongoDB的C#驱动。C# 驱动由两个类库组成:BSON Library和C# Driver。 BSON Library 可以独立于 C# Driver 使用。 C# Driver 则必须需要 BSON Library。

你还可能对 C# 驱动序列化教程 感兴趣。它是一个另外的教程因为它涵盖了很多资料。

下载

C# 驱动既有源代码也有二进制文件。BSON Library 和 C# Driver 都存在同一个知识库里,而BSON Library可以独立使用。

原文件可以从 github.com 进行下载。

我们使用 msysgit 作为我们的 Windows git 客户端。可以到这里进行下载: http://msysgit.github.com/.

要复制知识库的话,从git bash shell里运行以下命令:

$ cd <parentdirectory>
$ git config --global core.autocrlf true
$ git clone git://github.com/mongodb/mongo-csharp-driver.git
$ cd mongo-csharp-driver
$ git config core.autocrlf true

复制知识库之前,必须将core.autocrlf的全局设置设为true。当复制完毕后,我们建议你将core.autocrlf的本地设置设为true(如上所示),这样将来core.autocrlf的全局设置更改了也不会影响到这个知识库。如果你到时候想把全局设置的core.autocrlf改为false,则运行:

$ git config --global core.autocrlf false

core.autocrlf设置的典型问题是git 报告整个文件都被修改了(由于行结尾的差异)。在知识库创建后更改core.autocrlf的设置是相当没劲的,所以在开始时就设好它是很重要的。

你可以通过点击以下链接的Downloads按钮来下载源文件的 zip 文件 (不用复制知识库):

http://github.com/mongodb/mongo-csharp-driver

你可以在以下链接下载二进制文件(.msi 和 .zip 两种格式) :

http://github.com/mongodb/mongo-csharp-driver/downloads

生成

目前我们使用 Visual Studio 2010 来生成C# 驱动。解决方案的名称是 CSharpDriver-2010.sln.

依赖项

单元测试依赖 NUnit 2.5.9,它已包含在知识库的依赖项文件夹中。你可以不用安装NUnit就生成C#驱动,不过要运行单元测试则必须安装NUnit(除非你用别的测试运行器)

运行单元测试

有三个工程包含单元测试:

1. BsonUnitTests
2. DriverUnitTests
3. DriverUnitTestsVB

BsonUnitTests 不连接 MongoDB 服务端。DriverUnitTests 和 DriverUnitTestsVB 连接一个运行在localhost上默认端口的MongoDB实例。

运行单元测试的一个简单方法是将其中一个单元测试工程设为启动项目并遵照以下说明配置工程(用 BsonUnitTests 做例子):

  • 在”调试“页签里:
    1. 将”启动操作“设为”启动外部程序“
    2. 将外部程序设为: C:\Program Files (x86)\NUnit 2.5.9\bin\net-2.0\nunit.exe
    3. 将“命令行参数”设为: BsonUnitTests.csproj /config:Debug /run
    4. 将“工作目录”设为:  BsonUnitTest.csproj 所在的目录

如果还想为单元测试运行在Release模式的话,为Release配置重复以上步骤 (使用 /config:Release 代替) 。

nunit.exe的实际路径可能根据你的机器有轻微不同。

要运行 DriverUnitTests 和 DriverUnitTestsVB 执行相同的步骤 (如有必要适当修改).

安装

如果你想安装C#驱动到你的机器上,你可以用安装程序 (见上面的下载说明)。安装程序很简单,只需把DLL复制到指定安装目录即可。

如果你下载了二进制zip文件,只需简单地解压文件并把它们放到任意地方。

注意:如果你下载的是.zip 文件,Windows 可能要你 “解除锁定” 帮助文件。当你双击CSharpDriverDocs.chm文件时,如果 Windows 问你 “是否要打开此文件?” ,将“每次打开此文件时都询问”旁的复选框勾掉,然后再点击“打开”按钮。或者还可以在 CSharpDriverDocs.chm 文件上右键,选择“属性”,然后在“常规”页签的顶部点击“解除锁定”按钮。如果“解除锁定”按钮没显示的话,就没必要解除锁定了。

引用和命名空间

要使用 C# 驱动,需要添加以下DLL引用:

  1. MongoDB.Bson.dll
  2. MongoDB.Driver.dll

至少要在你的源文件里加上以下using语句:

using MongoDB.Bson;
using MongoDB.Driver;

另外还可能经常用到以下using语句:

using MongoDB.Driver.Builders;
using MongoDB.Driver.GridFS;
using MongoDB.Driver.Linq;

在某些情况下如果你要使用C#驱动的某些可选部分的话,还可能用上以下某些using语句:

using MongoDB.Bson.IO;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Bson.Serialization.Conventions;
using MongoDB.Bson.Serialization.IdGenerators;
using MongoDB.Bson.Serialization.Options;
using MongoDB.Bson.Serialization.Serializers;
using MongoDB.Driver.Wrappers;

BSON Library

C# 驱动在 BSON Library之上创建的。BSON Library处理BSON格式的所有细节,包括:I/O,序列化以及BSON文档的内存中对象模型。

BSON对象模型的重要类有: BsonType, BsonValue, BsonElement, BsonDocument 和 BsonArray.

BsonType

这个枚举用来指定BSON值得类型,定义为:

public enum BsonType {
    Double = 0x01,
    String = 0x02,
    Document = 0x03,
    Array = 0x04,
    Binary = 0x05,
    Undefined = 0x06,
    ObjectId = 0x07,
    Boolean = 0x08,
    DateTime = 0x09,
    Null = 0x0a,
    RegularExpression = 0x0b,
    JavaScript = 0x0d,
    Symbol = 0x0e,
    JavaScriptWithScope = 0x0f,
    Int32 = 0x10,
    Timestamp = 0x11,
    Int64 = 0x12,
    MinKey = 0xff,
    MaxKey = 0x7f
}

BsonValue 及其子类

BsonValue 是一个抽象类,表示一个BSON类型的值。BsonType枚举中定义的每一个值都对应了一个具体的BsonValue子类。要获取一个BsonValue实例有几种方法:

  • 使用一个BsonValue的子类的公共构造函数 (如果有的话)
  • 使用BsonValue的静态 Create 方法
  • 使用BsonValue的子类的静态 Create 方法
  • 使用BsonValue的子类的静态属性
  • 使用隐式转换到 BsonValue

使用静态 Create 方法的好处是它们可以为经常使用的值返回预创建实例。它们还可以返回null(构造函数却不能),当使用函数式构造创建BsonDocument处理可选元素时将很有用。静态属性引用经常使用的值的预创建实例。隐式转换允许你使用原生的.NET值,不管BsonValue是否需要,而且.NET值会自动转换为BsonValue。

BsonType 属性

BsonValue 有一个名为 BsonType 的属性,可以用来查询BsonValue的实际类型。以下例子演示判断BsonValue类型的几种方法:

BsonValue value;
if (value.BsonType == BsonType.Int32) {
    // 知道值是BsonInt32的实例
}
if (value is BsonInt32) {
    // 另一种知道值是BsonInt32的方法
}
if (value.IsInt32) {
    // 最简单的知道值是BsonInt32的方法
}

As[Type] 属性

BsonValue 有大量将BsonValue投射(cast)成它的子类或原生.NET类型的属性。注意很重要的一点是,这些属性都只是投射(cast),而不是转换(conversion)。如果BsonValue不是对应的类型的话,将抛出一个 InvalidCastException 异常。 参见 To[Type] 方法,它进行的就是转换操作,以及 Is[Type] 属性,你可以在尝试使用其中一个As[Type]属性前用它查询BsonValue的类型。

BsonDocument document;
string name = document["name"].AsString;
int age = document["age"].AsInt32;
BsonDocument address = document["address"].AsBsonDocument;
string zip = address["zip"].AsString;

Is[Type] 属性

BsonValue 有以下布尔属性,用来测试它是什么类型的BsonValue。这些可以如下使用:

BsonDocument document;
int age = -1;
if (document.Contains["age"] && document["age"].IsInt32) {
    age = document["age"].AsInt32;
}

To[Type] 转换方法

不像 As[Type] 方法,To[Type] 方法在可转换类型间,如int和double,执行同样的有限转换。

ToBoolean 方法从不失败。它使用 JavaScript 的似真非真定义: false, 0, 0.0, NaN, BsonNull, BsonUndefined 和 “” 都是false, 而其余的都是 true (包括字符串 “false”).

ToBoolean 方法当处理的文档可能对记录true/false值时有不确定方法时就显得特别有用:

if (employee["ismanager"].ToBoolean()) {
    // we know the employee is a manager
    // works with many ways of recording boolean values
}

ToDoubleToInt32, 和 ToInt64 方法当在数字类型间转换时从不失败,但是值如果不适合目标类型的话可能会被截断。字符串可以转换为数字类型,但如果字符串不能解析为目标类型的值的话将抛出异常。

静态Create方法

由于 BsonValue 是一个抽象类,你不能创建BsonValue的实例(只能创建具体子类的实例)。 BsonValue 有一个静态 Create 方法,参数只有一个,是object类型的,并在运行时确定要创建的BsonValue的实际类型。BsonValue的子类也有静态的 Create 方法,由它们的需求而定制。

隐式转换

隐式转换是从以下.NET类型到BsonValue定义的:

  • bool
  • byte[]
  • DateTime
  • double
  • Enum
  • Guid
  • int
  • long
  • ObjectId
  • Regex
  • string

这就不用再调用BsonValue构造函数或者Create方法了。例如:

BsonValue b = true; // b是一个 BsonBoolean 的实例
BsonValue d = 3.14159; // d 是一个 BsonDouble 的实例
BsonValue i = 1; // i 是一个 BsonInt32 的实例
BsonValue s = "Hello"; // s 是一个 BsonString 的实例

BsonMaxKey, BsonMinKey, BsonNull 和 BsonUndefined

这几个类都是单例的,所以每个类只有一个实例存在。要引用这些实例,使用每个类的静态 Value 属性:

document["status"] = BsonNull.Value;
document["priority"] = BsonMaxKey.Value;

注意 C# 的 null 和 BsonNull.Value 是两个不同的东西。后者其实是一个 C# 对象,表示一个 BSON null 值 (这是很细微的区别,但在功能结构里却扮演很重要的角色).

ObjectId 和 BsonObjectId

ObjectId 是一个结构体,维持一个BSON ObjectId的原始值。 BsonObjectId 是 BsonValue 的一个子类,其 Value 属性是ObjectId类型。

这里是一些创建ObjectId值的常用方法:

var id1 = new ObjectId(); // 和 ObjectId.Empty 一样
var id2 = ObjectId.Empty; // 全是0
var id3 = ObjectId.GenerateNewId(); // 生成新的唯一Id
var id4 = ObjectId.Parse("4dad901291c2949e7a5b6aa8"); // 解析24位十六进制数字串

注意第一个例子C#与JavaScript有不同的表现。在C#里它创建了一个全是0的 ObjectId ,不过在 JavaScript 里它生成一个新的唯一Id。这个差异无法避免,因为在C#里值类型的构造函数总是把值初始化为全0。

BsonElement

BsonElement 是一个键值对,值是一个 BsonValue。它好比BsonDocument的积木,由0或者更多的元素组成。一般很少直接创建 BsonElements ,因为它们通常是不需要直接创建的。例如:

document.Add(new BsonElement("age", 21)); // 没问题,但下一行更简短
document.Add("age", 21); // 自动创建BsonElement

BsonDocument

BsonDocument 是键值对(BsonElement)的集合 。 它是BSON文档的内存中对象模型。有三种方法创建并填充 BsonDocument:

  1. 创建一个新的文档并调用Add和Set方法
  2. 创建一个新的文档并连续调用Add和Set方法
  3. 创建一个新的文档并使用C#的集合初始化语法(推荐)

BsonDocument 构造函数

BsonDocument 有以下构造函数:

  • BsonDocument()
  • BsonDocument(string name, BsonValue value)
  • BsonDocument(BsonElement element)
  • BsonDocument(Dictionary<string, object> dictionary)
  • BsonDocument(Dictionary<string, object> dictionary, IEnumerable<string> keys)
  • BsonDocument(IDictionary dictionary)
  • BsonDocument(IDictionary dictionary, IEnumerable<string> keys)
  • BsonDocument(IDictionary<string, object> dictionary)
  • BsonDocument(IDictionary<string, object> dictionary, IEnumerable<string> keys)
  • BsonDocument(IEnumerabe<BsonElement> elements)
  • BsonDocument(params BsonElement[] elements)
  • BsonDocument(bool allowDuplicateNames)

前两个是最可能用到的。第一个创建一个空的文档,第二个以一个元素创建文档(这两种情况当然都可以添加更多元素)。

所有构造函数(除了那个有allowDuplicateNames参数的之外)都简单地调用了同参数的Add方法,所以参考相应的Add方法以了解新文档是如何初始化填充的。

BsonDocument 一般不允许有重复的名称,但如果你想有重复的名称的话,就调用带allowDuplicateNames参数的构造函数并传入true。不建议你使用重复的名称,此选项只是为了处理已有的可能存在重复名称的BSON文档。 MongoDB 不保证是否支持带重复名称的文档,所以发送此类文档到服务器是务必小心。

创建新文档并调用Add和Set方法

这是传统的用多行C#语句一步步创建并填充文档的方法。例如:

BsonDocument book = new BsonDocument();
book.Add("author", "Ernest Hemingway");
book.Add("title", "For Whom the Bell Tolls");

创建新文档并连续使用Add和Set方法

这个和前一个方法很类似,不过连续调用Add方法只需一行C#语句即可。例如:

BsonDocument book = new BsonDocument()
    .Add("author", "Ernest Hemingway")
    .Add("title", "For Whom the Bell Tolls");

创建新文档并使用C#集合初始化语法(推荐使用)

这是在一行语句中创建和初始化BsonDocument的推荐方法。它使用C#集合初始化语法:

BsonDocument book = new BsonDocument {
    { "author", "Ernest Hemingway" },
    { "title", "For Whom the Bell Tolls" }
};

编译器将这行代码翻译为与之匹配的Add方法:

    BsonDocument book = new BsonDocument();
    book.Add("author", "Ernest Hemingway");
    book.Add("title", "For Whom the Bell Tolls");

常见的错误时忘了写里面的花括弧。这会导致一个编译错误。例如:

BsonDocument bad = new BsonDocument {
    "author", "Ernest Hemingway"
};

会被编译器翻译成:

BsonDocument bad = new BsonDocument();
bad.Add("author");
bad.Add("Ernest Hemingway");

会导致编译错误因为没有Add方法是只接受一个string参数的。

创建嵌套的 BSON 文档

嵌套 BSON 文档通过设置元素的值为BSON文档来进行创建。例如:

BsonDocument nested = new BsonDocument {
    { "name", "John Doe" },
    { "address", new BsonDocument {
        { "street", "123 Main St." },
        { "city", "Centerville" },
        { "state", "PA" },
        { "zip", 12345}
    }}
};

这个创建了一个顶级文档,有两个元素 (“name” 和 “address”)。  “address” 的值是一个嵌套的 BSON 文档。

Add 方法

BsonDocument 有如下重载的Add方法

  • Add(BsonElement element)
  • Add(Dictionary<string, object> dictionary)
  • Add(Dictionary<string, object> dictionary, IEnumerable<string> keys)
  • Add(IDictionary dictionary)
  • Add(IDictionary dictionary, IEnumerable<string> keys)
  • Add(IDictionary<string, object> dictionary)
  • Add(IDictionary<string, object> dictionary, IEnumerable<string> keys)
  • Add(IEnumerable<BsonElement> elements)
  • Add(string name, BsonValue value)
  • Add(string name, BsonValue value, bool condition)

要注意的很重要的一点是有时候Add方法不会添加新元素。如果提供的值是null(或者最后一个重载中提供的condition是false)的话那元素就不会被添加。这在处理可选元素时就不用写任何if语句或者条件表达式了。

例如:

BsonDocument document = new BsonDocument {
    { "name", name },
    { "city", city }, // 如果city是null就不添加
    { "dob", dob, dobAvailable } // 如果 dobAvailable是false则不添加
};

就比下面更简洁和可读性强:

BsonDocument document = new BsonDocument();
document.Add("name", name);
if (city != null) {
    document.Add("city", city);
}
if (dobAvailable) {
    document.Add("dob", dob);
}

如果你想在值缺失的情况下添加一个BsonNull,你可能会这么做。但更简单的方法是使用C#的??运算符:

BsonDocument = new BsonDocument {
    { "city", city ?? BsonConstants.Null }
};

IDictionary 重载从一个字典初始化一个 BsonDocument 。字典里的每一个键都变成元素的name,每一个值都映射为匹配的 BsonValue 并变成新元素的value。带keys参数的重载让你选择加载哪个字典入口(还可能用keys参数来控制从字典里加载元素的顺序)。

访问 BsonDocument 元素

访问 BsonDocument 元素的推荐做法是使用下面的索引:

  • BsonValue this[int index]
  • BsonValue this[string name]
  • BsonValue this[string name, BsonValue defaultValue]

注意索引的返回值是 BsonValue,而不是 BsonElement。这其实让 BsonDocuments 更容易使了 (如果你需要获取实际的 BsonElements ,那就用 GetElement方法).

我们已经看过访问 BsonDocument 元素的例子了。这里再来几个:

BsonDocument book;
string author = book["author"].AsString;
DateTime publicationDate = book["publicationDate"].AsDateTime;
int pages = book["pages", -1].AsInt32; // 默认值是 -1

BsonArray

这个类用来表示 BSON 数组。由于BSON文档(元素用特殊命名惯例)恰巧对外表示为数组, BsonArray 类跟 BsonDocument 类是无关的,因为它俩用起来很不一样。

构造函数

BsonArray 有以下构造函数:

  • BsonArray()
  • BsonArray(IEnumerable<bool> values)
  • BsonArray(IEnumerable<BsonValue> values)
  • BsonArray(IEnumerable<DateTime> values)
  • BsonArray(IEnumerable<double> values)
  • BsonArray(IEnumerable<int> values)
  • BsonArray(IEnumerable<long> values)
  • BsonArray(IEnumerable<ObjectId> values)
  • BsonArray(IEnumerable<string> values)
  • BsonArray(IEnumerable values)

所有带参数的构造函数都调用匹配的Add方法。由于C#不提供自动从IEnumerable<T> 到 IEnumerable<object>的转换,所以多重载是有必要的。

Add 和 AddRange 方法

BsonArray 具有以下的 Add 方法:

  • BsonArray Add(BsonValue value)
  • BsonArray AddRange(IEnumerable<bool> values)
  • BsonArray AddRange(IEnumerable<BsonValue> values)
  • BsonArray AddRange(IEnumerable<DateTime> values)
  • BsonArray AddRange(IEnumerable<double> values)
  • BsonArray AddRange(IEnumerable<int> values)
  • BsonArray AddRange(IEnumerable<long> values)
  • BsonArray AddRange(IEnumerable<ObjectId> values)
  • BsonArray AddRange(IEnumerable<string> values)
  • BsonArray AddRange(IEnumerable values)

注意Add方法只有一个参数。要创建并以多个值初始化一个 BsonArray ,请使用以下方法之一:

// 传统方法
BsonArray a1 = new BsonArray();
a1.Add(1);
a2.Add(2);

// 连续调用
BsonArray a2 = new BsonArray().Add(1).Add(2);

// values参数
int[] values = new int[] { 1, 2 };
BsonArray a3 = new BsonArray(values);

// 集合初始化语法
BsonArray a4 = new BsonArray { 1, 2 };

索引

数组元素用整型索引进行访问。比如 BsonDocument,元素的类型是 BsonValue。比如:

BsonArray array = new BsonArray { "Tom", 39 };
string name = array[0].AsString;
int age = array[1].AsInt32;

C# 驱动

知道现在我们讨论的都是 BSON 类库。剩下的我们来说一下 C# 驱动。

线程安全

只有一小部分C#驱动是线程安全的。它们是: MongoClient, MongoServer, MongoDatabase, MongoCollection 和 MongoGridFS。通常用的比较多的类都不是线程安全的,包括 MongoCursor 和所有BSON类库里的类 (除了 BsonSymbolTable 是线程安全的). 不特别标记为线程安全的都是线程非安全的。

所有类的所有静态属性和方法都是线程安全的。

MongoClient 类

这个类是操控MongoDB服务器的根对象。与服务器的连接是自动在后台处理的 (用了一个连接池来提升效率).

当连接到一个副本是,用的仍然只有一个MongoClient的实例,它代表一个完整的副本。驱动会自动找出所有副本里的成员并识别出当前的主服务器。

这个类的实例是线程安全的。

操作默认情况下,除非设置了,否则,所有的操作需要WriteConcern使用W = 1。换句话说,默认情况下,所有的写操作都会阻塞,直到服务器已经确认。

连接字符串

连接MongoDB服务器的最简单方法就是使用连接字符串。标准的连接字符串格式为:

mongodb://[username:password@]hostname[:port][/[database][?options]]

username 和 password 只有在MongoDB服务器使用了身份验证时才出现。这些凭证信息将是所有数据库的默认凭证。要验证admin数据库,在username里加上 “(admin)” 。如果要根据不同数据库使用不同的凭证,在GetDatabase方法里传入正确的凭证即可。

端口号是可选的,默认为 27017.

要连接多个服务器的话,用逗号分隔多个主机名(和端口号,如果有的话)。例如:

mongodb://server1,server2:27017,server2:27018

这个连接字段串指定了三个服务器 (其中两个在同一台机器上,但端口号不一样)。由于指定多个服务器会引起歧义,不知道到底是副本还是多个mongo(分片安装中),服务器会进入一个连接的发现阶段来确定它们的类型。这对于连接时间而言有点过头了,不过可以通过在连接字符串里指定连接模式来避免:

mongodb://server1,server2:27017,server2:27018/?connect=replicaset

可选的模式有:自动 automatic (默认), 直接 direct, 副本replica set, 和 分片路由 shardrouter。连接模式的规则如下:

1. 如果连接模式指定为自动以外的,则使用之。
2. 如果在连接字符串里指定了副本名称 (replicaset), 那么将使用副本模式。
3. 如果连接字符串里只列出了一个服务器,那么将使用直接模式。
4. 否则,将查找第一个响应的服务器,确定连接模式。

如果列出了多个服务器,而且其中一个是副本,别的不是,那么连接模式就不可确定了。确保别在连接字符串里混用服务器类型。

如果连接模式设为副本模式,驱动会去找主服务器,即使它不在字符串里列出,只要字符串里至少有一个服务器响应了(响应里将包含完整的副本和当前的主服务器名称)。另外,其它服务器也会被找到并自动添加(或移除),甚至在初始化连接之后。这样你就可以从副本里添加和移除服务器,驱动会自动处理这些变更。

正像上面所说的,连接字符串的可选部分是用来设置各种连接选项的。假设你想要直接连接到副本的一个成员不管它是不是当前主服务器(可能想监控它的状态或者仅仅读查询)。你可以这么写:

mongodb://server2/?connect=direct;readpreference=nearest

连接字符串的完整文档可以看下面的连接:

http://www.mongodb.org/display/DOCS/Connections

和:

http://docs.mongodb.org/manual/applications/replication/#replica-set-read-preference

对SSL 的支持

驱动里已经支持了SSL。可以通过在连接字符串里加上 “ssl=true” 选项来进行配置。

mongodb://server2/?ssl=true

默认情况下,服务器证书会对本地受信任证书存储进行验证。这经常会在测试服务器没有签名证书的测试环境里引起一些问题。要缓和这个问题,可以添加另一个连接字符串选项 “sslverifycertificate=false” 来忽略任何证书错误。

身份认证

MongoDB 支持简单直接的身份认证机制。你可以在 security and authentication docs page 了解更多。

C# 驱动有多种方法支持身份验证。上面提到的连接字符串,可以指定默认凭证信息。通常在没有提供其它凭证的时候都会用默认凭证。

有两种方法来提供凭证。第一种,可以在运行时通过特定方法提供。这些凭证就会被用来执行想要的功能。第二种,也是更健壮的方法,是把凭证存储在 MongoCredentialsStore 里。存在里面的 MongoCredentials 由数据库作为键值,所以如果不同的数据库需要不同的用户,那么凭证存储先去找第一个,如果没找着,就退而求其次,看连接字符串里有没有提供默认凭证,有则用之。

下面的例子使用了凭证存储来定义”foo”数据的管理员凭证。使用“admin”或者“foo”以外的凭证去访问数据将使用提供了默认凭证“test”的连接字符串。

var url = new MongoUrl("mongodb://test:user@localhost:27017");
var settings = MongoClientSettings.FromUrl(url);
var adminCredentials = new MongoCredentials("admin", "user", true);
settings.CredentialsStore.Add("admin", adminCredentials);
var fooCredentials = new MongoCredentials("foo", "user", false);
settings.CredentialsStore.Add("foo", fooCredentials);

var client = new MongoClient(settings);

GetServer 方法

要从 MongoClient 的实例取得 MongoServer 的实例可以使用 GetServer 方法。

MongoServer 类

MongoServer 类是用来对驱动进行更多的控制。包含了获取数据库和通过简单的socket发布一系列操作的高级方法,为的是保证一致性。

GetDatabase 方法

从 MongoServer 实例取得 MongoDatabase 实例(见下一节) 可以使用以下的 GetDatabase 方法或索引之一:

  • MongoDatabase GetDatabase(MongoDatabaseSettings settings)
  • MongoDatabase GetDatabase(string databaseName)
  • MongoDatabase GetDatabase(string databaseName, MongoCredentials credentials)
  • MongoDatabase GetDatabase(string databaseName, MongoCredentials credentials, WriteConcern writeConcern)
  • MongoDatabase GetDatabase(string databaseName, WriteConcern writeConcern)

样例代码:

MongoClient client = new MongoClient(); // 连接到 localhost
MongoServer server = client.GetServer();
MongoDatabase test = server.GetDatabase("test");
MongoCredentials credentials = new MongoCredentials("username", "password");
MongoDatabase salaries = server.GetDatabase("salaries", credentials);

大多数的数据设置都是从服务器对象继承来的, GetDatabase 提供的重载可以对经常使用的设置进行覆盖。要覆盖其它设置,调用 CreateDatabaseSettings 并在调用 GetDatabase 之前更改任何你想要的设置,像这样:

var databaseSettings = server.CreateDatabaseSettings("test");
databaseSettings.SlaveOk = true;
var database = server.GetDatabase(databaseSettings);

GetDatabase 维系了一个 MongoDatabase 之前返回过的 实例表,因此如果以同样的参数再次调用 GetDatabase 会再次得到相同的实例。

RequestStart/RequestDone 方法

有时候为了保证结果正确,需要在同一个连接里执行一系列操作。这比较少见,而且大多数时候没有必要去调用 RequestStart/RequestDone。有必要这么做的一个例子是在w=0的WriteConcern的快速会话中调用了一系列的Insert,然后紧接着马上查询出这些数据来(在w=0的WriteConcern下,服务器里的写操作会排队,而且可能不会马上对其它连接可见)。使用 RequestStart 可以在同一个连接里在写的时候强制查询,因此查询直到服务器捕获了写操作之后才会执行。

通过使用RequestStart 和 RequestDone,线程可以从连接池里暂时保留一个连接,例如:

using(server.RequestStart(database)) {
// 在同一个连接里需要执行一系列操作
}

database 参数只是简单地说明你要在这个请求期间要用哪些数据库。这使服务器能够对已经身份验证通过的数据库拿来就用 (如果没用身份验证那这个优化就没关系了)。在这个请求期间你可以任意地使用其它数据库了。

RequestStart (为这个线程)增加了一个计数,在完成后再减掉。保留的连接实际不是返回到连接池里,直到计数再次变为0。这说明嵌套调用 RequestStart 是没有问题的。

RequestStart 返回了一个 IDisposable。如果是在using块里用 RequestStart ,为了释放连接最好尽快调用 RequestDone 。

其它的属性和方法

参考其它的属性和方法,请参阅api文档。

MongoDatabase 类

这个类表示 MongoDB 服务器的数据库。通常每个数据库只有一个实例,除非你是用不同的设置来访问同一个数据库,这样就是每个设置都有一个实例。

这个类的实例是线程安全的。

GetCollection 方法

此方法返回一个表示数据库里集合的对象。当请求一个集合对象时,要同时制定集合的默认文档类型。例如:

MongoDatabase hr = server.GetDatabase("hr");
MongoCollection<Employee> employees =
    hr.GetCollection<Employee>("employees");

集合并不限于只有一种文档。默认的文档类型在处理那种文档时能更方便一点,但在需要时你完全可以指定另一种文档。

大多数的集合设置是从数据库继承的,GetCollection 提供的重载可以对常用的设置进行覆盖。要覆盖其它的设置,调用 CreateCollectionSettings 并在调用 GetCollection 之前更改任何你想要的设置,像这样:

var collectionSettings = database.CreateCollectionSettings<TDocument>("test");
collectionSettings.SlaveOk = true;
var collection = database.GetCollection(collectionSettings);

GetCollection 维系了之前返回过的一个实例表,因此如果以同样的参数再次调用 GetCollection 会得到同一个实例。

其它属性和方法

参考其它的属性和方法,请参阅api文档。

MongoCollection<TDefaultDocument> 类

此类表示 MongoDB 数据库里的集合。 <TDefaultDocument> 泛型参数指定了此集合默认文档的类型。

此类的实例是线程安全的。

Insert<TDocument> 方法

要在集合里插入一个文档,创建一个表示该文档的对象并调用 Insert。对象可以是BsonDocument 的实例或者是可以成功序列化为BSON文档的任何类的实例。例如:

MongoCollection<BsonDocument> books =
    database.GetCollection<BsonDocument>("books");
BsonDocument book = new BsonDocument {
    { "author", "Ernest Hemingway" },
    { "title", "For Whom the Bell Tolls" }
};
books.Insert(book);

如果有一个名为 Book 的类,代码如下:

MongoCollection<Book> books = database.GetCollection<Book>("books");
Book book = new Book {
    Author = "Ernest Hemingway",
    Title = "For Whom the Bell Tolls"
};
books.Insert(book);

InsertBatch 方法

使用InserBatch方法可以一次性插入多个文档,例如:

MongoCollection<BsonDocument> books;
BsonDocument[] batch = {
    new BsonDocument {
        { "author", "Kurt Vonnegut" },
        { "title", "Cat's Cradle" }
    },
    new BsonDocument {
        { "author", "Kurt Vonnegut" },
        { "title", "Slaughterhouse-Five" }
    }
};
books.InsertBatch(batch);

插入多个文档时,使用 InsertBatch 比 Insert 效率更高。

FindOne 和 FindOneAs 方法

要从集合里获取文档,使用Find方法之一。FindOne是最简单的一个。它返回找到的第一个文档(当有多个文档时你没法确定是哪一个)。例如:

MongoCollection<Book> books;
Book book = books.FindOne();

如果要读取一个类型不是 <TDefaultDocument> 的文档,就使用 FindOneAs 方法,可以覆盖其返回文档的类型,例如:

MongoCollection<Book> books;
BsonDocument document = books.FindOneAs<BsonDocument>();

这里集合的默认文档类型是 Book,但我们将其覆盖了,指定结果为 BsonDocument 的实例。

Find 和 FindAs 方法

Find 和 FindAs 方法通过接受一个查询,告诉服务器要返回那个文档。 query 参数是 IMongoQuery 类型的。 IMongoQuery 接口标记了类可以用来进行查询。构建查询的最常用方法是要么使用Query建造类,要么自己创建一个QueryDocument (QueryDocument 是BsonDocument 的子类,同时实现了 IMongoQuery 因此可以用作查询对象)。同时,通过使用 QueryWrapper 类,查询可以是任何能序列化为BSON文档的类型,不过这取决于你得保证序列化后的文档表示的是一个有效的查询对象。

其中一种查询方法是自己创建 QueryDocument 对象:

MongoCollection<BsonDocument> books;
var query = new QueryDocument("author", "Kurt Vonnegut");
foreach (BsonDocument book in books.Find(query)) {
    // do something with book
}

另一种方法是使用 Query Builder (推荐):

MongoCollection<BsonDocument> books;
var query = Query.EQ("author", "Kurt Vonnegut");
foreach (BsonDocument book in books.Find(query)) {
    // do something with book
}

还有另一种查询的方法是使用匿名类,不过这样我们得把匿名对象进行封装:

MongoCollection<BsonDocument> books;
var query = Query.Wrap(new { author = "Kurt Vonnegut" });
foreach (BsonDocument book in books.Find(query)) {
    // do something with book
}

如果想要读取不是默认类型的文档,则使用 FindAs 方法:

MongoCollection<BsonDocument> books;
var query = Query<Book>.EQ(b => b.Author, "Kurt Vonnegut");
foreach (Book book in books.FindAs<Book>(query)) {
    // do something with book
}

Save<TDocument> 方法

Save 方法是 Insert 和 Update的组合。如果文档的 Id 有值,那么就假定这是一个已经存在的文档,Save就会在文档上调用Update(设置Upsert标记以防止它实际上是个新文档)。否则就假定这是一个新文档,Save会在首先将新生成的唯一值设到Id上,然后调用Insert。

例如,要修正一本书的书名错误:

MongoCollection<BsonDocument> books;
var query = Query.And(
    Query.EQ("author", "Kurt Vonnegut"),
    Query.EQ("title", "Cats Craddle")
);
BsonDocument book = books.FindOne(query);
if (book != null) {
    book["title"] = "Cat's Cradle";
    books.Save(book);
}

调用Save方法的时候,TDocument 类必须要有Id。如果没有的话可以调用Insert来插入文档。

Update 方法

Update 方法用来更新已有文档。Save方法的示例代码还可以写成:

MongoCollection<BsonDocument> books;
var query = new QueryDocument {
    { "author", "Kurt Vonnegut" },
    { "title", "Cats Craddle" }
};
var update = new UpdateDocument {
    { "$set", new BsonDocument("title", "Cat's Cradle") }
};
BsonDocument updatedBook = books.Update(query, update);

或者使用 Query 和 Update builders:

MongoCollection<BsonDocument> books;
var query = Query.And(
    Query.EQ("author", "Kurt Vonnegut"),
    Query.EQ("title", "Cats Craddle")
);
var update = Update.Set("title", "Cat's Cradle");
BsonDocument updatedBook = books.Update(query, update);

FindAndModify 方法

当你想要查找一个文档并在一个原子操作里更新它时,就使用 FindAndModify。 FindAndModify 只更新一个文档,配合使用具有排序标准的多文档查询来确定到底要更新哪个文档。另外, FindAndModify 会返回符合条件的文档 (不管是在更新前还是更新后) 而且可以指定要返回文档的那些字段。

参考以下链接中的例子:

http://www.mongodb.org/display/DOCS/findAndModify+Command

对 FindAndModify 的调用如下:

var jobs = database.GetCollection("jobs");
var query = Query.And(
    Query.EQ("inprogress", false),
    Query.EQ("name", "Biz report")
);
var sortBy = SortBy.Descending("priority");
var update = Update.
    .Set("inprogress", true)
    .Set("started", DateTime.UtcNow);
var result = jobs.FindAndModify(
    query,
    sortBy,
    update,
    true // return new document
);
var chosenJob = result.ModifiedDocument;

MapReduce 方法

Map/Reduce 是从集合里汇总数据的一种方法。集合里的每一个文档(或者某些子集,如果可选查询提供了的话)都被传到map函数,该函数调用emit来产生中间值。然后中间值被传到reduce函数进行汇总。

下面的例子摘选自Kristina Chodorow 和 Michael Dirolf写的《MongoDB权威指南》第87页。它计算了集合里的每一个键值被找到了多少次。

var map =
    "function() {" +
    "    for (var key in this) {" +
    "        emit(key, { count : 1 });" +
    "    }" +
    "}";

var reduce =
    "function(key, emits) {" +
    "    total = 0;" +
    "    for (var i in emits) {" +
    "        total += emits[i].count;" +
    "    }" +
    "    return { count : total };" +
    "}";

var mr = collection.MapReduce(map, reduce);
foreach (var document in mr.GetResults()) {
    Console.WriteLine(document.ToJson());
}

其它属性和方法

参考其它的属性和方法,请参阅api文档。

MongoCursor<TDocument> 类

Find 方法(以及它的各个变种) 不是马上返回查询的实际结果。而是返回一个能获取到查询结果的可遍历的游标。查询实际上并不是传到服务器,直到尝试获取第一个结果(技术上而言,就是在由GetEnumerator返回的枚举器第一次调用MoveNext时)。这说明了我们可以在获取到结果之前以各种有趣的方式来控制查询的结果。

MongoCursor 的实例不是线程安全的,至少在它们冻结(见下面)前是不安全的。一旦它们冻结了,它们就是线程安全的了,因为它们是只读的(尤其是,GetEnumerator是线程安全的,所以同一个游标可以被多个线程使用)。

遍历游标

要使用查询结果最方便的方法就是用C#的foreach语句。例如:

var query = Query.EQ("author", "Ernest Hemingway");
var cursor = books.Find(query);
foreach (var book in cursor) {
    // do something with book
}

还可以用LINQ为IEnumerable<T>定义的扩展方法来遍历游标:

var query = Query.EQ("author", "Ernest Hemingway");
var cursor = books.Find(query);
var firstBook = cursor.FirstOrDefault();
var lastBook = cursor.LastOrDefault();
在上边的例子,查询实际上传到服务器两次(分别是 FirstOrDefault 和 LastOrDefault 调用的时候).

很重要的一点是游标将其引用的资源都释放干净了。要保证这一点的关键是确保调用了枚举器的Dispose方法。foreach语句和LINQ扩展方法都保证了Dispose会被调用。除非你手动遍历右边,那就得自己负责调用 Dispose。

遍历游标前修改它

游标有几个属性可以在遍历控制返回结果前进行修改。有两种修改游标的方法:

  1. 直接修改属性
  2. 使用平滑接口来设置属性

例如,如果想要取第101到110个结果,可以这样写:

var query = Query.EQ("status", "pending");
var cursor = tasks.Find(query);
cursor.Skip = 100;
cursor.Limit = 10;
foreach (var task in cursor) {
    // do something with task
}

或者使用平滑接口:

var query = Query.EQ("status", "pending");
foreach (var task in tasks.Find(query).SetSkip(100).SetLimit(10)) {
    // do something with task
}

平滑接口在只设置少部分值时用着很爽。当设置比较多时可能用属性方式更好一点。

一旦开始遍历游标,它就变成“冻结”,你就不能再更改任何属性了。所以要在遍历前就设置好所有的属性。

游标的可修改属性

以下是游标的可修改属性:

  • BatchSize (SetBatchSize)
  • Fields (SetFields)
  • Flags (SetFlags)
  • Limit (SetLimit)
  • Options (SetOption and SetOptions)
  • SerializationOptions (SetSerializationOptions)
  • Skip (SetSkip)
  • SlaveOk (SetSlaveOk)

括号里的方法名是对应的平滑接口方法。

平滑接口还支持额外的不常使用的选项,这些选项没有对应的属性:

  • SetHint
  • SetMax
  • SetMaxScan
  • SetMin
  • SetShowDiskLoc
  • SetSnapshot
  • SetSortOrder

其它方法

MongoCursor 有一些方法用于某些特殊操作目的:

  • Clone
  • Count
  • Explain
  • Size

WriteConcern 类

WriteConcern 有好几级,这个类就是用来表示这些级次的。 WriteConcern 只是应用在那些没有返回值的操作 (所以它不应用在查询和命令中)。它应用于这几个 MongoCollection 方法: Insert, Remove, Save 和 Update.

WriteConcern 的要领是在 Insert, Remove, Save 或者 Update之后,紧接着调用GetLastError命令将消息发送到服务器,这样驱动就可以操作成功了。另外,当使用副本时,有可能确认信息被复制到最少量的辅服务器上去。

【.net】未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序解决办法 - willingtolove - 博客园

mikel阅读(1096)

来源: 【.net】未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序解决办法 – willingtolove – 博客园

 

正文

#错误描述:

在开发.net项目中,通过microsoft.ACE.oledb读取excel文件信息时,报错:

  “未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序”

#代码示例:

复制代码
 1      static void Main(string[] args)
 2         {
 3             readexcel("D:\\test\\xlsxtest.xlsx");
 4         }
 5         public static void readexcel(string _path)
 6         {
 7             DataTable dt = new DataTable();
 8             string connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + _path + ";" + "Extended Properties=\"Excel 12.0;HDR=No\"";
 9 
10             using (OleDbConnection connection = new OleDbConnection(connectionString))
11             {
12                 string SQL = "select * from [sheet1$]";
13                 try
14                 {
15                     OleDbCommand comm = new OleDbCommand(SQL, connection);
16                     if (connection.State != ConnectionState.Open)
17                         connection.Open();
18                     OleDbDataAdapter Adpter = new OleDbDataAdapter(comm);
19                     Adpter.Fill(dt);
20                 }
21                 catch (Exception ex)
22                 {
23                     dt = null;
24                 }
25                 finally
26                 {
27                     if (connection.State == ConnectionState.Open)
28                         connection.Close();
29                 }
30 
31                 foreach (DataRow item in dt.Rows)
32                 {
33                     string sds = item[0].ToString();
34                     Console.WriteLine(item[0].ToString() + "//" + item[1].ToString() + "//" + item[2].ToString());
35                     if (item[1].ToString() == string.Empty)
36                     {
37                         break;
38                     }
39                 }
40                 Console.ReadKey();
41             }
42         }
复制代码

 

#报错原因:

主要有以下几种原因:

1、没有安装数据访问组件,需要安装相应版本的数据访问组件(AccessDatabaseEngine);

2、没有安装相应版本的Office客户端,需要安装相应版本的Office客户端;

3、没有在IIS应用程序池配置默认属性,需要在相应的IIS应用程序池启用32位应用程序;

4、连接字符串的问题。采用Microsoft.Jet.OleDb.4.0,可以读取excel2007以前的版本,在客户机上不需要部署office,采用Microsoft.Ace.OleDb.12.0的时候,需要安装引擎。

5、顺便说一下,在使用“Microsoft.Jet.OLEDB.4.0”,也会报类似错误,原因有可能是,Microsoft.Jet.OLEDB.4.0在64位系统上不支持,需要修改架构,从x64改为x86,无论是WinForm还是ASP.NET;或者修改连接字符串为Microsoft.ACE.OLEDB.12.0并且安装AccessDatabaseEngine x64数据访问组件;

#解决方案:

  1、安装数据访问组件:

  1)适用于office2007的

  Microsoft Access Database Engine 2007 Office system 驱动程序:数据连接组件
  https://download.csdn.net/download/willingtolove/12584343  (亲测没问题!xls和xlsx格式都可以成功读取!)

  2)适用于office2010的

  Microsoft Access Database Engine 2010 Redistributable
  https://www.microsoft.com/zh-CN/download/details.aspx?id=13255 (亲测没问题!注意x64还是x86!)

  2、在IIS应用程序池中,设置“”启用兼容32位应用程序”,此设置适用于web项目;

  如图:

  
注意:
在下载Microsoft Access Database Engine 2010 Redistributable时会让选择下载x86的还是x64的,如图:
前提是看服务器是x64的还是x86的,x64的服务器两个版本都能安装;

  如果下载安装的是x64的,那么你的桌面程序就要选择x64发布,而web项目是不兼容的,不管你是如何发布的;

如果下载安装的是x86的,那么你的桌面程序就要选择x86发布,而web项目选AnyCPU正常发布就好;

*总结:如果你是web项目,你就下载x86的,发布选anycpu就好了,然后设置应用程序池32位兼容就好了;

*最后说一句,用这个,是不需要安装office软件的;

—————————————————————————————————————————————————————————–

  3、连接字符串

  Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\\myFolder\\myExcel2007file.xlsx;
  Extended Properties="Excel 12.0 Xml;HDR=YES";
    “HDR =Yes;” 表示第一行包含列名,而不是数据。“HDR =No;” 表明相反;
  Microsoft.ACE.OLEDB连接字符串参考地址:https://www.connectionstrings.com/ace-oledb-12-0/