zoukankan      html  css  js  c++  java
  • 【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;
            }
        }
    View Code

      然后对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(';')[0];
            public static readonly string database_Default = System.Configuration.ConfigurationManager.AppSettings["sqlConnectionStringMongo"].Split(';')[1].Split('=')[1];
    
            #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 ("000000000000000000000000".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 > 0)
                                {
                                    for (int index = 0; 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 == 0)
                {
                    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(1).FirstOrDefault();
            }
        }
    }
    View Code

       下面我将建一个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; }
        }
    View Code

      测试代码:

        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(1);
                users.Spell.Add(2);
                users.Spell.Add(3);
    
                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 + 40;
                });
    
                _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;
            }
        }
    View Code

      

  • 相关阅读:
    JavaScript function (简单总结)
    JavaScript 数组 (简单总结)
    yum update 和 yum upgrate 区别
    git clone警告,提示Warning:Permission denied (publickey)
    ''退格符号笔记
    MySQL Workbench导出Model提示['ERROR 1064 (42000): You have an error in your SQL syntax....syntax to use near 'VISIBLE']
    《Python编程从入门到实践》--- 学习过程笔记(3)列表
    《Python编程从入门到实践》--- 学习过程笔记(2)变量和简单数据类型
    Windows+MyEclipse+MySQL【连接数据库报错caching_sha2_password】
    测试 | 让每一粒尘埃有的放矢
  • 原文地址:https://www.cnblogs.com/nonkicat/p/5566057.html
Copyright © 2011-2022 走看看