【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>是 ...
随机推荐
- zabbix 监控web网站性能
一直在纠结用什么实例来给大家演示呢?想来想去还是官方的好,那我们怎么用zabbix监控web性能和可用性呢?我们这边分为几个步骤:打开网站.登陆.登陆验证.退出,一共4个小step,看实例. 检测流程 ...
- iOS地图 -- 定位初使用
iOS的定位服务用到的框架是#import <CoreLocation/CoreLocation.h> 定位中用到的类是CLLocationManager 一.iOS8.0之前的定位 向用 ...
- Java的多线程机制系列:(二)缓存一致性和CAS
一.总线锁定和缓存一致性 这是两个操作系统层面的概念.随着多核时代的到来,并发操作已经成了很正常的现象,操作系统必须要有一些机制和原语,以保证某些基本操作的原子性.首先处理器需要保证读一个字节或写一个 ...
- 最简单的JavaScript模板引擎
在小公司待久了感觉自己的知识面很小,最近逛博客园和一些技术网站看大家在说JavaScript模版引擎的事儿,完全没有概念,网上一搜这是08年开始流行起来的...本来以为这是很高深的知识,后来在网上看到 ...
- 对前端的一个H5项目的所思所想
最近接触一个前端HTML5的项目,虽然我主做iOS,但曾经也徒手用html+css+js+php写过一个博客,当然表示无压力了.结果.现在的前端发展的速度真是快啊,项目中用到Jquery,reactJ ...
- js cookie 数组 存读
自己研究了一下. "Cookie里面只能放String 类型" 所以只能将arr的数据按照自己的约定转成string格式存进cookie. 这里提示一下cookie是存在本地浏览器 ...
- Linux下查看软件的安装路径
一.which 命令 Shell 的which 命令可以找出相关命令是否已经在搜索路径中. $ which git/usr/bin/git 二.whereis 命令 whereis 命令搜索更大范围的 ...
- js下载浏览器中的图片
jquery function download(src) { var $a = $("<a></a>").attr("href", s ...
- ppt2013技术整理
1. 显示选择窗格 便于选择该页的所有元素.分组.隐藏与显示等. 位于:开始-编辑-选择-选择窗格 2. 显示动画窗格 便于调节页面中元素的动画状态. 位于:动画-高级动画-动画窗格 3. 绑定动画触 ...
- ImageView的常用属性
ImageView的一些常用属性,并且这些属性都有与之对应的getter.setter方法: android:adjustViewBounds:设置ImageView是否调整自己的边界来保持所显示图片 ...