一、前言

  最近项目中要用到MongoDB,因此实现做了不少的调研。发现网上很多现有关于MongoDB C#官方驱动的调用方法都是基于1.8版本的,已经不是用了最新的2.2版本。因此我在基于C#官方驱动2.2的基础上,对MongoDB的调用方法做了一些封装,以便于调用。

  封装的内容包括:

  1.封装了获取数据库及集合的方法

  2.封装了新增一条、多条数据的方法

  3.封装了更新一条、根据条件更新多条数据的方法,注意:是将对象统一更新成同一内容

  4.封装了删除一条,根据条件删除多条数据的方法。

  5.封装了根据Id获取单条数据,根据条件获取单条数据,获取集合首条数据的方法。

二、环境准备

  1 .NET Framework:4.5

  2 相关文档

    入门指南:http://mongodb.github.io/mongo-csharp-driver/2.2/getting_started/quick_tour/

    API文档:http://api.mongodb.org/csharp/2.2

  3 使用NuGet下载最新的驱动

    1)右键点击类库中【引用】,选择【管理NuGet程序包】

    

    2)联机搜索【mongodb driver】 ,选中安装下图中的3个类库,每个类库都是必须的.

   

、类库封装

  首先是MongoDB对象类的基础类,所有和MongoDB打交道的类都要基于这个类。

  1. public class MongoObj
  2. {
  3. public ObjectId _id { get; set; }
  4.  
  5. /// <summary>
  6. /// 将对象属性转成字典
  7. /// </summary>
  8. /// <returns></returns>
  9. public Dictionary<String, Object> ToMap()
  10. {
  11. Dictionary<String, Object> map = new Dictionary<string, object>();
  12.  
  13. Type t = this.GetType();
  14.  
  15. PropertyInfo[] pi = t.GetProperties(BindingFlags.Public | BindingFlags.Instance);
  16.  
  17. foreach (PropertyInfo p in pi)
  18. {
  19. MethodInfo mi = p.GetGetMethod();
  20.  
  21. if (mi != null && mi.IsPublic)
  22. {
  23. map.Add(p.Name, mi.Invoke(this, new Object[] { }));
  24. }
  25. }
  26.  
  27. return map;
  28. }
  29.  
  30. /// <summary>
  31. /// 将对象属性转成字典,并去掉字典中的_id.
  32. /// </summary>
  33. /// <returns></returns>
  34. public Dictionary<String, Object> ToMapWithoutId()
  35. {
  36. var map = ToMap();
  37.  
  38. if (map != null && map.Keys.Contains("_id"))
  39. {
  40. map.Remove("_id");
  41. }
  42.  
  43. return map;
  44. }
  45. }

  然后对MongoDB的调用方法进行封装。

  1. using DNElecCar.Data.Models.ViewModels;
  2. using MongoDB.Bson;
  3. using MongoDB.Driver;
  4. using System;
  5. using System.Collections;
  6. using System.Collections.Generic;
  7. using System.Linq;
  8. using System.Linq.Expressions;
  9. using System.Reflection;
  10.  
  11. namespace DNElecCar.Data.Repositories
  12. {
  13. /// <summary>
  14. /// mongodb的封装类,基于Mongodb C#官方驱动2.2版。
  15. /// </summary>
  16.  
  17. public sealed class MongoRepository
  18. {
  19.  
  20. public static readonly string connectionString_Default = System.Configuration.ConfigurationManager.AppSettings["sqlConnectionStringMongo"].Split(';')[];
  21. public static readonly string database_Default = System.Configuration.ConfigurationManager.AppSettings["sqlConnectionStringMongo"].Split(';')[].Split('=')[];
  22.  
  23. #region 获取数据库
  24.  
  25. public IMongoDatabase GetMongoDatabase()
  26. {
  27. return GetMongoDatabase(connectionString_Default, database_Default);
  28. }
  29.  
  30. public IMongoDatabase GetMongoDatabase(string connectionString, string databaseName)
  31. {
  32. var client = new MongoClient(connectionString);
  33.  
  34. var dbExists = client.ListDatabases().ToList().Any(o => o.Elements.Any(p => "name".Equals(p.Name) && databaseName.Equals(p.Value.AsString)));
  35. if (!dbExists)
  36. {
  37. throw new Exception("所请求的数据库不存在!");
  38. }
  39.  
  40. return client.GetDatabase(databaseName);
  41. }
  42.  
  43. #endregion
  44.  
  45. #region 获取集合
  46.  
  47. public IMongoCollection<T> GetMongoCollection<T>(string collectionName)
  48. {
  49. var myCollection = GetMongoCollection<T>(connectionString_Default, database_Default, collectionName);
  50.  
  51. return myCollection;
  52. }
  53.  
  54. public IMongoCollection<T> GetMongoCollection<T>(string connectionString, string databaseName, string collectionName)
  55. {
  56. var database = GetMongoDatabase(connectionString, databaseName);
  57.  
  58. var collectionFilter = new BsonDocument("name", collectionName);
  59. var collections = database.ListCollections(new ListCollectionsOptions { Filter = collectionFilter });
  60. if (!collections.ToList().Any())
  61. {
  62. throw new Exception("所请求的集合不存在!");
  63. }
  64.  
  65. var myCollection = database.GetCollection<T>(collectionName);
  66. return myCollection;
  67. }
  68. #endregion
  69.  
  70. #region 新增
  71.  
  72. public void InsertOne<T>(string collectionName, T entity)
  73. {
  74. InsertOne<T>(MongoRepository.connectionString_Default, MongoRepository.database_Default, collectionName, entity);
  75. }
  76.  
  77. public void InsertOne<T>(string connectionString, string databaseName, string collectionName, T entity)
  78. {
  79. if (null == entity) return;
  80.  
  81. var myCollection = GetMongoCollection<T>(connectionString, databaseName, collectionName);
  82.  
  83. myCollection.InsertOne(entity);
  84. }
  85.  
  86. public void InsertMany<T>(string collectionName, IEnumerable<T> entitys)
  87. {
  88. InsertMany<T>(MongoRepository.connectionString_Default, MongoRepository.database_Default, collectionName, entitys);
  89. }
  90.  
  91. public void InsertMany<T>(string connectionString, string databaseName, string collectionName, IEnumerable<T> entitys)
  92. {
  93.  
  94. if (null == entitys) return;
  95.  
  96. var myCollection = GetMongoCollection<T>(connectionString, databaseName, collectionName);
  97.  
  98. myCollection.InsertMany(entitys);
  99. }
  100.  
  101. #endregion
  102.  
  103. #region 修改
  104.  
  105. public void UpdateOrCreateOne<T>(string collectionName, T entity) where T : MongoObj
  106. {
  107. if ("".Equals(entity._id.ToString()))
  108. {
  109. InsertOne<T>(collectionName, entity);
  110. }
  111. else
  112. {
  113. UpdateOne<T>(collectionName, entity);
  114. }
  115. }
  116.  
  117. public void UpdateOne<T>(string collectionName, T entity) where T : MongoObj
  118. {
  119. UpdateOne<T>(MongoRepository.connectionString_Default, MongoRepository.database_Default, collectionName, entity);
  120. }
  121.  
  122. /// <summary>
  123. /// 更新集合属性,支持复杂类型的集合对象
  124. /// </summary>
  125. /// <typeparam name="T"></typeparam>
  126. /// <param name="connectionString"></param>
  127. /// <param name="databaseName"></param>
  128. /// <param name="collectionName"></param>
  129. /// <param name="entity"></param>
  130. public void UpdateOne<T>(string connectionString, string databaseName, string collectionName, T entity) where T : MongoObj
  131. {
  132. var myCollection = GetMongoCollection<T>(connectionString, databaseName, collectionName);
  133.  
  134. var filter = Builders<T>.Filter.Eq("_id", entity._id);
  135. var fieldList = GetUpdateDefinitions(entity);
  136.  
  137. myCollection.UpdateOne(filter, Builders<T>.Update.Combine(fieldList));
  138. }
  139.  
  140. #region 递归获取字段更新表达式
  141.  
  142. private List<UpdateDefinition<T>> GetUpdateDefinitions<T>(T entity)
  143. {
  144. var type = typeof(T);
  145. var fieldList = new List<UpdateDefinition<T>>();
  146.  
  147. foreach (var property in type.GetProperties(BindingFlags.Instance | BindingFlags.Public))
  148. {
  149. GenerateRecursion<T>(fieldList, property, property.GetValue(entity), entity, "");
  150. }
  151.  
  152. return fieldList;
  153. }
  154.  
  155. private void GenerateRecursion<TEntity>(
  156. List<UpdateDefinition<TEntity>> fieldList,
  157. PropertyInfo property,
  158. object propertyValue,
  159. TEntity item,
  160. string father)
  161. {
  162. //复杂类型
  163. if (property.PropertyType.IsClass && property.PropertyType != typeof(string) && propertyValue != null)
  164. {
  165. //集合
  166. if (typeof(IList).IsAssignableFrom(propertyValue.GetType()))
  167. {
  168. foreach (var sub in property.PropertyType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
  169. {
  170. if (sub.PropertyType.IsClass && sub.PropertyType != typeof(string))
  171. {
  172. var arr = propertyValue as IList;
  173. if (arr != null && arr.Count > )
  174. {
  175. for (int index = ; index < arr.Count; index++)
  176. {
  177. foreach (var subInner in sub.PropertyType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
  178. {
  179. if (string.IsNullOrWhiteSpace(father))
  180. GenerateRecursion(fieldList, subInner, subInner.GetValue(arr[index]), item, property.Name + "." + index);
  181. else
  182. GenerateRecursion(fieldList, subInner, subInner.GetValue(arr[index]), item, father + "." + property.Name + "." + index);
  183. }
  184. }
  185. }
  186. }
  187. }
  188. }
  189. //实体
  190. else
  191. {
  192. foreach (var sub in property.PropertyType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
  193. {
  194.  
  195. if (string.IsNullOrWhiteSpace(father))
  196. GenerateRecursion(fieldList, sub, sub.GetValue(propertyValue), item, property.Name);
  197. else
  198. GenerateRecursion(fieldList, sub, sub.GetValue(propertyValue), item, father + "." + property.Name);
  199. }
  200. }
  201. }
  202. //简单类型
  203. else
  204. {
  205. if (property.Name != "_id")//更新集中不能有实体键_id
  206. {
  207. if (string.IsNullOrWhiteSpace(father))
  208. fieldList.Add(Builders<TEntity>.Update.Set(property.Name, propertyValue));
  209. else
  210. fieldList.Add(Builders<TEntity>.Update.Set(father + "." + property.Name, propertyValue));
  211. }
  212. }
  213. }
  214.  
  215. /// <summary>
  216. /// 构建Mongo的更新表达式
  217. /// </summary>
  218. /// <param name="entity"></param>
  219. /// <returns></returns>
  220. private List<UpdateDefinition<T>> GeneratorMongoUpdate<T>(T item)
  221. {
  222. var fieldList = new List<UpdateDefinition<T>>();
  223. foreach (var property in typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public))
  224. {
  225. GenerateRecursion<T>(fieldList, property, property.GetValue(item), item, string.Empty);
  226. }
  227. return fieldList;
  228. }
  229.  
  230. #endregion
  231.  
  232. /// <summary>
  233. /// 更新指定条件的对象,更新结果为0,则新增一条数据
  234. /// </summary>
  235. /// <typeparam name="T"></typeparam>
  236. /// <param name="collectionName"></param>
  237. /// <param name="entity"></param>
  238. /// <param name="query"></param>
  239. public void UpdateAllOrCreateOne<T>(string collectionName, T entity, Expression<Func<T, bool>> query) where T : MongoObj
  240. {
  241. var updateResult = UpdateAll<T>(MongoRepository.connectionString_Default, MongoRepository.database_Default, collectionName, entity, query);
  242. if (updateResult.MatchedCount == )
  243. {
  244. InsertOne<T>(MongoRepository.connectionString_Default, MongoRepository.database_Default, collectionName, entity);
  245. }
  246. }
  247.  
  248. /// <summary>
  249. /// 更新所有对象更新为同一的对象值
  250. /// </summary>
  251. /// <typeparam name="T"></typeparam>
  252. /// <param name="collectionName"></param>
  253. /// <param name="entity">更新对象。 </param>
  254. /// <param name="query">条件查询。 调用示例:o=> o.UserName == "TestUser" 等等</param>
  255. /// <returns></returns>
  256. public UpdateResult UpdateAll<T>(string collectionName, T entity, Expression<Func<T, bool>> query) where T : MongoObj
  257. {
  258. return UpdateAll<T>(MongoRepository.connectionString_Default, MongoRepository.database_Default, collectionName, entity, query);
  259. }
  260.  
  261. /// <summary>
  262. /// 更新所有对象更新为同一的对象值
  263. /// </summary>
  264. /// <typeparam name="T"></typeparam>
  265. /// <param name="connectionString"></param>
  266. /// <param name="databaseName"></param>
  267. /// <param name="collectionName"></param>
  268. /// <param name="entity">更新对象。 </param>
  269. /// <param name="query">条件查询。 调用示例:o=> o.UserName == "TestUser" 等等</param>
  270. /// <returns></returns>
  271. public UpdateResult UpdateAll<T>(string connectionString, string databaseName, string collectionName, T entity, Expression<Func<T, bool>> query = null) where T : MongoObj
  272. {
  273. var myCollection = GetMongoCollection<T>(connectionString, databaseName, collectionName);
  274. var fieldList = GetUpdateDefinitions(entity);
  275.  
  276. return myCollection.UpdateMany<T>(query, Builders<T>.Update.Combine(fieldList));
  277. }
  278.  
  279. #endregion
  280.  
  281. #region 删除
  282.  
  283. public void Delete<T>(string collectionName, T entity) where T : MongoObj
  284. {
  285. Delete<T>(MongoRepository.connectionString_Default, MongoRepository.database_Default, collectionName, entity._id);
  286. }
  287.  
  288. public void Delete<T>(string connectionString, string databaseName, string collectionName, ObjectId _id)
  289. {
  290. var myCollection = GetMongoCollection<T>(connectionString, databaseName, collectionName);
  291. var filter = Builders<T>.Filter.Eq("_id", _id);
  292.  
  293. myCollection.DeleteOne(filter);
  294. }
  295.  
  296. public void Delete<T>(string collectionName, Expression<Func<T, bool>> query)
  297. {
  298.  
  299. Delete<T>(MongoRepository.connectionString_Default, MongoRepository.database_Default, collectionName, query);
  300. }
  301.  
  302. public void Delete<T>(string connectionString, string databaseName, string collectionName, Expression<Func<T, bool>> query)
  303. {
  304.  
  305. var myCollection = GetMongoCollection<T>(connectionString, databaseName, collectionName);
  306. if (query != null)
  307. {
  308. myCollection.DeleteManyAsync<T>(query);
  309. }
  310. }
  311.  
  312. #endregion
  313.  
  314. #region 获取单条信息
  315.  
  316. public T FirstOrDefault<T>(string collectionName, string _id)
  317. {
  318. return FirstOrDefault<T>(MongoRepository.connectionString_Default, MongoRepository.database_Default, collectionName, _id);
  319. }
  320.  
  321. public T FirstOrDefault<T>(string connectionString, string databaseName, string collectionName, string _id)
  322. {
  323. var myCollection = GetMongoCollection<T>(connectionString, databaseName, collectionName);
  324.  
  325. ObjectId id;
  326. if (!ObjectId.TryParse(_id, out id)) return default(T);
  327.  
  328. var filter = Builders<T>.Filter.Eq("_id", id);
  329. return myCollection.Find<T>(filter).First();
  330. }
  331.  
  332. /// <summary>
  333. ///
  334. /// </summary>
  335. /// <typeparam name="T"></typeparam>
  336. /// <param name="collectionName"></param>
  337. /// <param name="query">条件查询。 调用示例:o=> o.UserName == "username" 等等</param>
  338. /// <returns></returns>
  339.  
  340. public T FirstOrDefault<T>(string collectionName, Expression<Func<T, bool>> query)
  341. {
  342. return FirstOrDefault<T>(MongoRepository.connectionString_Default, MongoRepository.database_Default, collectionName, query);
  343. }
  344.  
  345. /// <summary>
  346. ///
  347. /// </summary>
  348. /// <typeparam name="T"></typeparam>
  349. /// <param name="connectionString"></param>
  350. /// <param name="databaseName"></param>
  351. /// <param name="collectionName"></param>
  352. /// <param name="query">条件查询。 调用示例:o=> o.UserName == "username" 等等</param>
  353. /// <returns></returns>
  354. public T FirstOrDefault<T>(string connectionString, string databaseName, string collectionName, Expression<Func<T, bool>> query)
  355. {
  356. var myCollection = GetMongoCollection<T>(connectionString, databaseName, collectionName);
  357.  
  358. T result = default(T);
  359.  
  360. if (query != null)
  361. {
  362. result = myCollection.Find<T>(query).FirstOrDefault();
  363. }
  364.  
  365. return result;
  366.  
  367. }
  368.  
  369. #endregion
  370.  
  371. }
  372.  
  373. /// <summary>
  374. /// mongodb的封装类的拓展方法。
  375. /// </summary>
  376. public static class MongoRepositoryExt
  377. {
  378. /// <summary>
  379. /// 获取结合的首条数据
  380. /// </summary>
  381. /// <typeparam name="T"></typeparam>
  382. /// <param name="collection"></param>
  383. /// <returns></returns>
  384. public static T FirstOne<T>(this IMongoCollection<T> collection)
  385. {
  386. return collection.AsQueryable().Take().FirstOrDefault();
  387. }
  388. }
  389. }

   下面我将建一个User集合,并对这个User集合进行增删改查。

   Users:

  1. public class Users : MongoObj
  2. {
  3. public string ObjectId_id { get; set; }
  4. public string Name { get; set; }
  5. public string Sex { set; get; }
  6. public List<int> Spell { get; set; }
  7. }

  测试代码:

  1. public class TestLogic
  2. {
  3. private MongoDBHelper _mongo;
  4.  
  5. public TestLogic()
  6. {
  7. _mongo = new MongoDBHelper();
  8. }
  9.  
  10. public int Insert()
  11. {
  12. Users users = new Users()
  13. {
  14. Name = "test",
  15. Sex="man",
  16. Spell = new List<int>()
  17. };
  18.  
  19. users.Spell.Add();
  20. users.Spell.Add();
  21. users.Spell.Add();
  22.  
  23. var collection = _mongo.GetMongoCollection<Users>("User");
  24. collection.InsertOne(users);
  25.  
  26. return collection.AsQueryable().Count();
  27. }
  28.  
  29. public int Delete()
  30. {
  31. var collection = _mongo.GetMongoCollection<Users>("User");
  32. var first = collection.FirstOne<Users>();
  33.  
  34. _mongo.Delete<Users>("User", first);
  35.  
  36. return collection.AsQueryable().Count();
  37. }
  38.  
  39. public int DeleteMany()
  40. {
  41. var collection = _mongo.GetMongoCollection<Users>("User");
  42.  
  43. _mongo.DeleteMany<Users>("User", o => o.Sex == "man");
  44.  
  45. return collection.AsQueryable().Count();
  46. }
  47.  
  48. public int Update()
  49. {
  50. var collection = _mongo.GetMongoCollection<Users>("User");
  51. var first = collection.FirstOne<Users>();
  52. first.Sex = "女";
  53. first.Name = "Update";
  54. first.Spell.ForEach(o =>
  55. {
  56. first.Spell[first.Spell.IndexOf(o)] = o + ;
  57. });
  58.  
  59. _mongo.UpdateOne("User", first);
  60.  
  61. return collection.AsQueryable().Count();
  62. }
  63.  
  64. public string GetOne()
  65. {
  66. var user = _mongo.FirstOrDefault<Users>("User", o => o.Sex == "女");
  67.  
  68. return user == null ? "" : user.Name;
  69. }
  70. }

  

【MongoDB】 基于C#官方驱动2.2版的封装类的更多相关文章

  1. MongoDB:利用官方驱动改装为EF代码风格的MongoDB.Repository框架 一

    本人系新接触MongoDB不久,属于MongoDB的菜鸟范畴.在使用MongoDB的过程中,总结了一些认识,在此总结跟大家分享.欢迎拍砖. 关于MongoDB的内容,在此就不做介绍了,网上有浩如烟海的 ...

  2. MongoDB学习笔记~官方驱动的原生Curd操作

    回到目录 MongoDB的官方C#驱动,让我们使用起来也很方便,但对于Linq开发人员来说,可能有些不了解,所以,我还是将官方驱动进行了二次封装,而对于一个比较个性化的mongo操作,使用我封装的也很 ...

  3. MongoDB:利用官方驱动改装为EF代码风格的MongoDB.Repository框架 三

    本次改动的主要内容是实现MongoDB.Repository在MongoDB中建立索引. 建立索引主要使用MongoDB的官方驱动中EnsureIndex方法. 在MongoDB.Repository ...

  4. C#版的mongodb最新的官方驱动2.4.0版本

    已经升级了mongodb至最新的3.4的版本,我想想也该把驱动升到最新的了,我用的驱动还是1.7的版本呢,之前几次想升级,都是因为升级驱动需要改动的代码太大了,升级的成本很高,所以懒得动,就这么的用了 ...

  5. MongoDB学习笔记~官方驱动嵌套数组对象的更新

    回到目录 对于数组对象mongodb本身是支持的,不过对于数组的更新,mongodb的Csharp驱动目前只支持一级,即你的对象里包含数组,而数组又包括数组,这表示两层,这在更新子数组时,Csharp ...

  6. MongoDB:利用官方驱动改装为EF代码风格的MongoDB.Repository框架 二

    本次改动的主要内容是实现MongoDB.Repository对MongoDBRef的支持. MongoDB对一对一,一对多,多对多关系的维护,官方推荐文档嵌入方式,反映到模型的设计如下: public ...

  7. MongoDB的C#官方驱动InvalidOperationException异常的解决办法

    异常情况描述 有一个“文章”类,其中包含一个“List<段落>”类型的属性,“段落”类是抽象类,其子类有“副标题段落”.“文本段落”.“图像段落”.“附件段落”.“列表段落”等类型. 将“ ...

  8. MongoDB:利用官方驱动改装为EF代码风格的MongoDB.Repository框架 六:支持多数据库操作

    本次主要内容:修正MongoDB.Repository框架对多数据库的支持. 在之前的五篇文章中对MongoDB.Repository框架做了简单的介绍是实现思路.之前是考虑MongoDB.Repos ...

  9. MongoDB:利用官方驱动改装为EF代码风格的MongoDB.Repository框架 五 --- 为List<MongoDBRef>增加扩展方法

    本次改动主要内容:为List<MongoDBRef>增加扩展方法 在MongoDB.Repository的使用过程中,发现在一个类中只定义一个List<MongoDBRef>是 ...

随机推荐

  1. 【OpenJudge 191】【POJ 1189】钉子和小球

    http://noi.openjudge.cn/ch0405/191/ http://poj.org/problem?id=1189 一开始忘了\(2^{50}\)没超long long差点写高精度Q ...

  2. iOS小知识点(UI部分)

    1. 父视图通过Tag来找到UIView UIView *targetView = [superView viewWithTag:10];//只在当前视图以及subviews中找,不能再孙子中找. 2 ...

  3. cmd命令快速修改dns

    新建cmd文件,修改红色ip部分,以 ANSI 编码保存,双击运行即可快速修改dns配置 netsh interface ip set dns "本地连接" source=stat ...

  4. java制作验证码

    建立一个web工程

  5. js 时间操作和随机数操作

    function Data() { var date = new Date(); var year = date.getFullYear(); ; var strDate = date.getDate ...

  6. python更新后yum问题

    How to switch between Python versions on Fedora Linux Currently, the default python version on Fedor ...

  7. asp rs开启关闭问题

    使用rs.close关闭后,可以直接用rs.open来打开数据表:如果用了set rs = nothing 从内存中清除rs对象,再次加载rs对象就需要使用set rs=server.createob ...

  8. mod-mono

    http://go-mono.com/config-mod-mono/  配置文件生成器 Mono remote debugging from Visual Studio http://stackov ...

  9. 深入理解javascript原型和闭包(8)——简述【执行上下文】上

    什么是“执行上下文”(也叫做“执行上下文环境”)?暂且不下定义,先看一段代码: 第一句报错,a未定义,很正常.第二句.第三句输出都是undefined,说明浏览器在执行console.log(a)时, ...

  10. jQuery验证控件jquery.validate.js使用说明

    官网地址:http://bassistance.de/jquery-plugins/jquery-plugin-validation jQuery plugin: Validation 使用说明 转载 ...