【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程序包】

    【MongoDB】 基于C#官方驱动2.2版的封装类

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

   【MongoDB】 基于C#官方驱动2.2版的封装类

、类库封装

  首先是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;
}
}

  

上一篇:wpf新增记录时用多线程的问题


下一篇:AFN的初步封装(post、GET、有无参数)