【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>是 ...
随机推荐
- 教你一招:Win10系统如何正确卸载edge浏览器?
Edge浏览器作为Win10系统默认浏览器,尽管我们将其他浏览器设置为默认程序,但是有时候还是会自动弹出,非常的不爽,但是在控制面板中却又找不到卸载“Edge”浏览器的选项.下面小编就教大家卸载“Ed ...
- 用java下载hdfs文件报NullPointerException
用fs.copyToLocalFile( hdfsPath,localPath);下载hdfs的文件会报NullPointerException,具体报错为: java.lang.NullPointe ...
- JS中匿名函数$(function(){ })和(function(){})()的区别
“$(function(){ });” Jquery语法的匿名函数,用于存放操作DOM对象的代码,执行其中代码时DOM对象已存在: (通过这样就可以在页面加载完成时通过ajax再异步加载一些数据) “ ...
- Jedis测试redis
首先:Jedis是redis的java版本的客户端. public class JedisTest { //单机版测试Jedis,不使用连接池 @Test public void testJedis( ...
- 《Python核心编程》18.多线程编程(三)
18.6使用threading模块 #!/usr/bin/env python # -*- coding:utf-8 -*- """从Thread类中派生出一个子例,创建 ...
- (转)PostgreSQL 兼容Oracle - orafce
转自:http://blog.163.com/digoal@126/blog/static/1638770402015112144250486/ PostgreSQL是和Oracle最接近的企业数据库 ...
- 前端工具之Gulp
Gulp是一款前端自动化的工具,如果能熟练使用Gulp来进行开发一定可以节省很多的时间,也可以快速的提高工作效率. 在使用Gulp之前就是要配置好Gulp安装的环境,这是我们能使用Gulp快速开发的第 ...
- golang笔记——数组与切片
一.切片的定义 我们可以从数组(go语言中很少直接使用数组)或者切片来初始化一个新的切片,也可以直接通过 make 来初始化一个所有元素为默认零值的切片. //1.通过数组来初始化切片 arr := ...
- Digital calculation
No1=1 No2=2 1. let result=No1+No2 let No1++ let No1+=3 2. result=$[No1+No2] 3. result=$((No1+No ...
- util类中非静态方法中注入serivce,在controller层是使用util。
今天碰到如题的问题,刚一开始在util中注入service总是注入失败,起初我以为是util中没有注入成功,debug看了一下果然注入不进来. 然后各种纠结,最终坑爹的问题是在controller直接 ...