一、前言

  最近项目中要用到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版的封装类的更多相关文章

  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. js中遍历删除数组中的项(项目中遇到的问题解决)

    代码如下: for (var key=0;key<$scope.pageContent.messages.length;key++){ if($scope.pageContent.message ...

  2. CocoaPods第三方库管理 iOS

    越来越多的SVN管理,越来越多的工程文件,我不能总是那么一个一个的把第三方库拖进去,我厌倦了拖拽和配置,我找到了替代方法--CocoaPods 补充一下:最近在给新机子安装时 发现 sudo gem ...

  3. 在github上搭建hexo博客

    准备工作 安装git 系统是win10家庭版,采用git v1.9.5版本,比较简单,一路next直到finsh完成安装. 安装node.js hexo是基于node.js驱动的一款快速.简单且功能强 ...

  4. 11月1日上午PHP------empty、 is_null、isset、unset的区别

    1.empty 判断一个变量是否为"空".null.false.00.0.'0′.』.为以上值的变量在检测時都将返回true. 2.isset 判断一个变量是否已经设置.0.00. ...

  5. C#环境

  6. ARCGIS常用几种本地数据AE初始化

    1.Personal GDB 新建一个在E盘的名为test的mdb: IWorkspaceFactory workspaceFactory = new AccessWorkspaceFactoryCl ...

  7. ArcEngine地图窗口指定区域导出指定DPI多格式---delphi/C#实现

    delphi/C#实现,其他语言稍微改下就行了.AE的编码各个语言都差不多,这里也没用到某一语言的特性. 函数特点: 1.可以精确导出指定范围的图形要素 2.支持多格式.TIF, .EMF,.GIF, ...

  8. thinkphp3.2与phpexcel带图片生成 完美案例

    thinkphp3.2与phpexcel完美案例 // 导出exl public function look_down(){ $id = I('get.id'); $m = M ('offer_goo ...

  9. 在Application中集成Microsoft Translator服务之开发前准备

    第一步:准备一个微软账号 要使用Microsoft Translator API需要在Microsoft Azure Marketplace(https://datamarket.azure.com/ ...

  10. NOSDK--SDK一键打包及统一接入的实现(前言)

    前言 一,一键打包的实现 1.1 shell脚本执行流程介绍 1.2 自动刷新mk文件的脚本介绍 1.3 编译及拷贝资源的脚本介绍 1.4 打包及签名的脚本介绍 1.5 mac下的脚本环境配置及脚本的 ...