【MongoDB】 基于C#官方驱动2.2版的封装类
一、前言
最近项目中要用到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打交道的类都要基于这个类。
- public class MongoObj
- {
- public ObjectId _id { get; set; }
- /// <summary>
- /// 将对象属性转成字典
- /// </summary>
- /// <returns></returns>
- public Dictionary<String, Object> ToMap()
- {
- Dictionary<String, Object> map = new Dictionary<string, object>();
- Type t = this.GetType();
- PropertyInfo[] pi = t.GetProperties(BindingFlags.Public | BindingFlags.Instance);
- foreach (PropertyInfo p in pi)
- {
- MethodInfo mi = p.GetGetMethod();
- if (mi != null && mi.IsPublic)
- {
- map.Add(p.Name, mi.Invoke(this, new Object[] { }));
- }
- }
- return map;
- }
- /// <summary>
- /// 将对象属性转成字典,并去掉字典中的_id.
- /// </summary>
- /// <returns></returns>
- public Dictionary<String, Object> ToMapWithoutId()
- {
- var map = ToMap();
- if (map != null && map.Keys.Contains("_id"))
- {
- map.Remove("_id");
- }
- return map;
- }
- }
然后对MongoDB的调用方法进行封装。
- using DNElecCar.Data.Models.ViewModels;
- using MongoDB.Bson;
- using MongoDB.Driver;
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Linq;
- using System.Linq.Expressions;
- using System.Reflection;
- namespace DNElecCar.Data.Repositories
- {
- /// <summary>
- /// mongodb的封装类,基于Mongodb C#官方驱动2.2版。
- /// </summary>
- public sealed class MongoRepository
- {
- public static readonly string connectionString_Default = System.Configuration.ConfigurationManager.AppSettings["sqlConnectionStringMongo"].Split(';')[];
- public static readonly string database_Default = System.Configuration.ConfigurationManager.AppSettings["sqlConnectionStringMongo"].Split(';')[].Split('=')[];
- #region 获取数据库
- public IMongoDatabase GetMongoDatabase()
- {
- return GetMongoDatabase(connectionString_Default, database_Default);
- }
- public IMongoDatabase GetMongoDatabase(string connectionString, string databaseName)
- {
- var client = new MongoClient(connectionString);
- var dbExists = client.ListDatabases().ToList().Any(o => o.Elements.Any(p => "name".Equals(p.Name) && databaseName.Equals(p.Value.AsString)));
- if (!dbExists)
- {
- throw new Exception("所请求的数据库不存在!");
- }
- return client.GetDatabase(databaseName);
- }
- #endregion
- #region 获取集合
- public IMongoCollection<T> GetMongoCollection<T>(string collectionName)
- {
- var myCollection = GetMongoCollection<T>(connectionString_Default, database_Default, collectionName);
- return myCollection;
- }
- public IMongoCollection<T> GetMongoCollection<T>(string connectionString, string databaseName, string collectionName)
- {
- var database = GetMongoDatabase(connectionString, databaseName);
- var collectionFilter = new BsonDocument("name", collectionName);
- var collections = database.ListCollections(new ListCollectionsOptions { Filter = collectionFilter });
- if (!collections.ToList().Any())
- {
- throw new Exception("所请求的集合不存在!");
- }
- var myCollection = database.GetCollection<T>(collectionName);
- return myCollection;
- }
- #endregion
- #region 新增
- public void InsertOne<T>(string collectionName, T entity)
- {
- InsertOne<T>(MongoRepository.connectionString_Default, MongoRepository.database_Default, collectionName, entity);
- }
- public void InsertOne<T>(string connectionString, string databaseName, string collectionName, T entity)
- {
- if (null == entity) return;
- var myCollection = GetMongoCollection<T>(connectionString, databaseName, collectionName);
- myCollection.InsertOne(entity);
- }
- public void InsertMany<T>(string collectionName, IEnumerable<T> entitys)
- {
- InsertMany<T>(MongoRepository.connectionString_Default, MongoRepository.database_Default, collectionName, entitys);
- }
- public void InsertMany<T>(string connectionString, string databaseName, string collectionName, IEnumerable<T> entitys)
- {
- if (null == entitys) return;
- var myCollection = GetMongoCollection<T>(connectionString, databaseName, collectionName);
- myCollection.InsertMany(entitys);
- }
- #endregion
- #region 修改
- public void UpdateOrCreateOne<T>(string collectionName, T entity) where T : MongoObj
- {
- if ("".Equals(entity._id.ToString()))
- {
- InsertOne<T>(collectionName, entity);
- }
- else
- {
- UpdateOne<T>(collectionName, entity);
- }
- }
- public void UpdateOne<T>(string collectionName, T entity) where T : MongoObj
- {
- UpdateOne<T>(MongoRepository.connectionString_Default, MongoRepository.database_Default, collectionName, entity);
- }
- /// <summary>
- /// 更新集合属性,支持复杂类型的集合对象
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="connectionString"></param>
- /// <param name="databaseName"></param>
- /// <param name="collectionName"></param>
- /// <param name="entity"></param>
- public void UpdateOne<T>(string connectionString, string databaseName, string collectionName, T entity) where T : MongoObj
- {
- var myCollection = GetMongoCollection<T>(connectionString, databaseName, collectionName);
- var filter = Builders<T>.Filter.Eq("_id", entity._id);
- var fieldList = GetUpdateDefinitions(entity);
- myCollection.UpdateOne(filter, Builders<T>.Update.Combine(fieldList));
- }
- #region 递归获取字段更新表达式
- private List<UpdateDefinition<T>> GetUpdateDefinitions<T>(T entity)
- {
- var type = typeof(T);
- var fieldList = new List<UpdateDefinition<T>>();
- foreach (var property in type.GetProperties(BindingFlags.Instance | BindingFlags.Public))
- {
- GenerateRecursion<T>(fieldList, property, property.GetValue(entity), entity, "");
- }
- return fieldList;
- }
- private void GenerateRecursion<TEntity>(
- List<UpdateDefinition<TEntity>> fieldList,
- PropertyInfo property,
- object propertyValue,
- TEntity item,
- string father)
- {
- //复杂类型
- if (property.PropertyType.IsClass && property.PropertyType != typeof(string) && propertyValue != null)
- {
- //集合
- if (typeof(IList).IsAssignableFrom(propertyValue.GetType()))
- {
- foreach (var sub in property.PropertyType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
- {
- if (sub.PropertyType.IsClass && sub.PropertyType != typeof(string))
- {
- var arr = propertyValue as IList;
- if (arr != null && arr.Count > )
- {
- for (int index = ; index < arr.Count; index++)
- {
- foreach (var subInner in sub.PropertyType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
- {
- if (string.IsNullOrWhiteSpace(father))
- GenerateRecursion(fieldList, subInner, subInner.GetValue(arr[index]), item, property.Name + "." + index);
- else
- GenerateRecursion(fieldList, subInner, subInner.GetValue(arr[index]), item, father + "." + property.Name + "." + index);
- }
- }
- }
- }
- }
- }
- //实体
- else
- {
- foreach (var sub in property.PropertyType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
- {
- if (string.IsNullOrWhiteSpace(father))
- GenerateRecursion(fieldList, sub, sub.GetValue(propertyValue), item, property.Name);
- else
- GenerateRecursion(fieldList, sub, sub.GetValue(propertyValue), item, father + "." + property.Name);
- }
- }
- }
- //简单类型
- else
- {
- if (property.Name != "_id")//更新集中不能有实体键_id
- {
- if (string.IsNullOrWhiteSpace(father))
- fieldList.Add(Builders<TEntity>.Update.Set(property.Name, propertyValue));
- else
- fieldList.Add(Builders<TEntity>.Update.Set(father + "." + property.Name, propertyValue));
- }
- }
- }
- /// <summary>
- /// 构建Mongo的更新表达式
- /// </summary>
- /// <param name="entity"></param>
- /// <returns></returns>
- private List<UpdateDefinition<T>> GeneratorMongoUpdate<T>(T item)
- {
- var fieldList = new List<UpdateDefinition<T>>();
- foreach (var property in typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public))
- {
- GenerateRecursion<T>(fieldList, property, property.GetValue(item), item, string.Empty);
- }
- return fieldList;
- }
- #endregion
- /// <summary>
- /// 更新指定条件的对象,更新结果为0,则新增一条数据
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="collectionName"></param>
- /// <param name="entity"></param>
- /// <param name="query"></param>
- public void UpdateAllOrCreateOne<T>(string collectionName, T entity, Expression<Func<T, bool>> query) where T : MongoObj
- {
- var updateResult = UpdateAll<T>(MongoRepository.connectionString_Default, MongoRepository.database_Default, collectionName, entity, query);
- if (updateResult.MatchedCount == )
- {
- InsertOne<T>(MongoRepository.connectionString_Default, MongoRepository.database_Default, collectionName, entity);
- }
- }
- /// <summary>
- /// 更新所有对象更新为同一的对象值
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="collectionName"></param>
- /// <param name="entity">更新对象。 </param>
- /// <param name="query">条件查询。 调用示例:o=> o.UserName == "TestUser" 等等</param>
- /// <returns></returns>
- public UpdateResult UpdateAll<T>(string collectionName, T entity, Expression<Func<T, bool>> query) where T : MongoObj
- {
- return UpdateAll<T>(MongoRepository.connectionString_Default, MongoRepository.database_Default, collectionName, entity, query);
- }
- /// <summary>
- /// 更新所有对象更新为同一的对象值
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="connectionString"></param>
- /// <param name="databaseName"></param>
- /// <param name="collectionName"></param>
- /// <param name="entity">更新对象。 </param>
- /// <param name="query">条件查询。 调用示例:o=> o.UserName == "TestUser" 等等</param>
- /// <returns></returns>
- public UpdateResult UpdateAll<T>(string connectionString, string databaseName, string collectionName, T entity, Expression<Func<T, bool>> query = null) where T : MongoObj
- {
- var myCollection = GetMongoCollection<T>(connectionString, databaseName, collectionName);
- var fieldList = GetUpdateDefinitions(entity);
- return myCollection.UpdateMany<T>(query, Builders<T>.Update.Combine(fieldList));
- }
- #endregion
- #region 删除
- public void Delete<T>(string collectionName, T entity) where T : MongoObj
- {
- Delete<T>(MongoRepository.connectionString_Default, MongoRepository.database_Default, collectionName, entity._id);
- }
- public void Delete<T>(string connectionString, string databaseName, string collectionName, ObjectId _id)
- {
- var myCollection = GetMongoCollection<T>(connectionString, databaseName, collectionName);
- var filter = Builders<T>.Filter.Eq("_id", _id);
- myCollection.DeleteOne(filter);
- }
- public void Delete<T>(string collectionName, Expression<Func<T, bool>> query)
- {
- Delete<T>(MongoRepository.connectionString_Default, MongoRepository.database_Default, collectionName, query);
- }
- public void Delete<T>(string connectionString, string databaseName, string collectionName, Expression<Func<T, bool>> query)
- {
- var myCollection = GetMongoCollection<T>(connectionString, databaseName, collectionName);
- if (query != null)
- {
- myCollection.DeleteManyAsync<T>(query);
- }
- }
- #endregion
- #region 获取单条信息
- public T FirstOrDefault<T>(string collectionName, string _id)
- {
- return FirstOrDefault<T>(MongoRepository.connectionString_Default, MongoRepository.database_Default, collectionName, _id);
- }
- public T FirstOrDefault<T>(string connectionString, string databaseName, string collectionName, string _id)
- {
- var myCollection = GetMongoCollection<T>(connectionString, databaseName, collectionName);
- ObjectId id;
- if (!ObjectId.TryParse(_id, out id)) return default(T);
- var filter = Builders<T>.Filter.Eq("_id", id);
- return myCollection.Find<T>(filter).First();
- }
- /// <summary>
- ///
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="collectionName"></param>
- /// <param name="query">条件查询。 调用示例:o=> o.UserName == "username" 等等</param>
- /// <returns></returns>
- public T FirstOrDefault<T>(string collectionName, Expression<Func<T, bool>> query)
- {
- return FirstOrDefault<T>(MongoRepository.connectionString_Default, MongoRepository.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">条件查询。 调用示例:o=> o.UserName == "username" 等等</param>
- /// <returns></returns>
- public T FirstOrDefault<T>(string connectionString, string databaseName, string collectionName, Expression<Func<T, bool>> query)
- {
- var myCollection = GetMongoCollection<T>(connectionString, databaseName, collectionName);
- T result = default(T);
- if (query != null)
- {
- result = myCollection.Find<T>(query).FirstOrDefault();
- }
- return result;
- }
- #endregion
- }
- /// <summary>
- /// mongodb的封装类的拓展方法。
- /// </summary>
- public static class MongoRepositoryExt
- {
- /// <summary>
- /// 获取结合的首条数据
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="collection"></param>
- /// <returns></returns>
- public static T FirstOne<T>(this IMongoCollection<T> collection)
- {
- return collection.AsQueryable().Take().FirstOrDefault();
- }
- }
- }
下面我将建一个User集合,并对这个User集合进行增删改查。
Users:
- public class Users : MongoObj
- {
- public string ObjectId_id { get; set; }
- public string Name { get; set; }
- public string Sex { set; get; }
- public List<int> Spell { get; set; }
- }
测试代码:
- public class TestLogic
- {
- private MongoDBHelper _mongo;
- public TestLogic()
- {
- _mongo = new MongoDBHelper();
- }
- public int Insert()
- {
- Users users = new Users()
- {
- Name = "test",
- Sex="man",
- Spell = new List<int>()
- };
- users.Spell.Add();
- users.Spell.Add();
- users.Spell.Add();
- var collection = _mongo.GetMongoCollection<Users>("User");
- collection.InsertOne(users);
- return collection.AsQueryable().Count();
- }
- public int Delete()
- {
- var collection = _mongo.GetMongoCollection<Users>("User");
- var first = collection.FirstOne<Users>();
- _mongo.Delete<Users>("User", first);
- return collection.AsQueryable().Count();
- }
- public int DeleteMany()
- {
- var collection = _mongo.GetMongoCollection<Users>("User");
- _mongo.DeleteMany<Users>("User", o => o.Sex == "man");
- return collection.AsQueryable().Count();
- }
- public int Update()
- {
- var collection = _mongo.GetMongoCollection<Users>("User");
- var first = collection.FirstOne<Users>();
- first.Sex = "女";
- first.Name = "Update";
- first.Spell.ForEach(o =>
- {
- first.Spell[first.Spell.IndexOf(o)] = o + ;
- });
- _mongo.UpdateOne("User", first);
- return collection.AsQueryable().Count();
- }
- public string GetOne()
- {
- var user = _mongo.FirstOrDefault<Users>("User", o => o.Sex == "女");
- return user == null ? "" : user.Name;
- }
- }
【MongoDB】 基于C#官方驱动2.2版的封装类的更多相关文章
- MongoDB:利用官方驱动改装为EF代码风格的MongoDB.Repository框架 一
本人系新接触MongoDB不久,属于MongoDB的菜鸟范畴.在使用MongoDB的过程中,总结了一些认识,在此总结跟大家分享.欢迎拍砖. 关于MongoDB的内容,在此就不做介绍了,网上有浩如烟海的 ...
- MongoDB学习笔记~官方驱动的原生Curd操作
回到目录 MongoDB的官方C#驱动,让我们使用起来也很方便,但对于Linq开发人员来说,可能有些不了解,所以,我还是将官方驱动进行了二次封装,而对于一个比较个性化的mongo操作,使用我封装的也很 ...
- MongoDB:利用官方驱动改装为EF代码风格的MongoDB.Repository框架 三
本次改动的主要内容是实现MongoDB.Repository在MongoDB中建立索引. 建立索引主要使用MongoDB的官方驱动中EnsureIndex方法. 在MongoDB.Repository ...
- C#版的mongodb最新的官方驱动2.4.0版本
已经升级了mongodb至最新的3.4的版本,我想想也该把驱动升到最新的了,我用的驱动还是1.7的版本呢,之前几次想升级,都是因为升级驱动需要改动的代码太大了,升级的成本很高,所以懒得动,就这么的用了 ...
- MongoDB学习笔记~官方驱动嵌套数组对象的更新
回到目录 对于数组对象mongodb本身是支持的,不过对于数组的更新,mongodb的Csharp驱动目前只支持一级,即你的对象里包含数组,而数组又包括数组,这表示两层,这在更新子数组时,Csharp ...
- MongoDB:利用官方驱动改装为EF代码风格的MongoDB.Repository框架 二
本次改动的主要内容是实现MongoDB.Repository对MongoDBRef的支持. MongoDB对一对一,一对多,多对多关系的维护,官方推荐文档嵌入方式,反映到模型的设计如下: public ...
- MongoDB的C#官方驱动InvalidOperationException异常的解决办法
异常情况描述 有一个“文章”类,其中包含一个“List<段落>”类型的属性,“段落”类是抽象类,其子类有“副标题段落”.“文本段落”.“图像段落”.“附件段落”.“列表段落”等类型. 将“ ...
- MongoDB:利用官方驱动改装为EF代码风格的MongoDB.Repository框架 六:支持多数据库操作
本次主要内容:修正MongoDB.Repository框架对多数据库的支持. 在之前的五篇文章中对MongoDB.Repository框架做了简单的介绍是实现思路.之前是考虑MongoDB.Repos ...
- MongoDB:利用官方驱动改装为EF代码风格的MongoDB.Repository框架 五 --- 为List<MongoDBRef>增加扩展方法
本次改动主要内容:为List<MongoDBRef>增加扩展方法 在MongoDB.Repository的使用过程中,发现在一个类中只定义一个List<MongoDBRef>是 ...
随机推荐
- 【OpenJudge 191】【POJ 1189】钉子和小球
http://noi.openjudge.cn/ch0405/191/ http://poj.org/problem?id=1189 一开始忘了\(2^{50}\)没超long long差点写高精度Q ...
- iOS小知识点(UI部分)
1. 父视图通过Tag来找到UIView UIView *targetView = [superView viewWithTag:10];//只在当前视图以及subviews中找,不能再孙子中找. 2 ...
- cmd命令快速修改dns
新建cmd文件,修改红色ip部分,以 ANSI 编码保存,双击运行即可快速修改dns配置 netsh interface ip set dns "本地连接" source=stat ...
- java制作验证码
建立一个web工程
- js 时间操作和随机数操作
function Data() { var date = new Date(); var year = date.getFullYear(); ; var strDate = date.getDate ...
- python更新后yum问题
How to switch between Python versions on Fedora Linux Currently, the default python version on Fedor ...
- asp rs开启关闭问题
使用rs.close关闭后,可以直接用rs.open来打开数据表:如果用了set rs = nothing 从内存中清除rs对象,再次加载rs对象就需要使用set rs=server.createob ...
- mod-mono
http://go-mono.com/config-mod-mono/ 配置文件生成器 Mono remote debugging from Visual Studio http://stackov ...
- 深入理解javascript原型和闭包(8)——简述【执行上下文】上
什么是“执行上下文”(也叫做“执行上下文环境”)?暂且不下定义,先看一段代码: 第一句报错,a未定义,很正常.第二句.第三句输出都是undefined,说明浏览器在执行console.log(a)时, ...
- jQuery验证控件jquery.validate.js使用说明
官网地址:http://bassistance.de/jquery-plugins/jquery-plugin-validation jQuery plugin: Validation 使用说明 转载 ...