• mongdo通用类(C#版)


        日前从公司离职,很快,还没休息就步入了现在的公司,开始跟着公司的脚步走。

        公司的项目基本都是大数据的,所以在数据库上大部分都是使用Mongodb和Redis,基本都是Nosql型的数据库为主。以前自己学着做过Mongodb和Redis的Demo,大体知道其怎么去运用,只是没有一个规范化的封装和运用,单纯是学习。现在有实战项目了,就激起了我前进学习的心,趁着今天自己查了下一些资料,学习了借鉴了一些前辈的方法后自己也封装了一个Mongdb的底层通用类,这里分享出来跟大家一起学习下。

        这里主要是讲我封装的底层,不涉及到Mongodb的安装,启动,可视化查询等东西,后面会附上一些参考的地址供大家一起学习。

        目前mongodb提供的驱动主要有两种:

        1.官网驱动  下载地址:http://github.com/mongodb/mongo-csharp-driver/downloads

               2.第三方的samus驱动 下载地址:https://github.com/samus/mongodb-csharp

         两个驱动的运用自己都有使用过,个人感觉官方的驱动提供的方法比较多,用起来也比较顺手,而且更新度比samus的高,所以自己使用的是官方的驱动。

       

      

          官网驱动的简单使用

          主要使用下面的两个dll

        MongoDB.dll          驱动的主要程序

        MongoDB.GridFS.dll    用于存储大文件。

          基本的增删改查代码如下:

       
    //数据库连接字符串
    
    const string strconn = "mongodb://127.0.0.1:27017";
    
    //数据库名称
    
    const string dbName = "cnblogs";
    
    //定义数据库
    
    MongoDatabase db;
    
    
    
    /// <summary>
    
    /// 打开数据库链接
    
    /// </summary>
    
    public void GetConnection()
    
    {
    
    //定义Mongo服务
    
     Mongo mongo = new Mongo(strconn);
    
    //打开连接
    
     mongo.Connect();
    
    //获得数据库cnblogs,若不存在则自动创建
    
     db = mongo.GetDatabase(dbName) as MongoDatabase;
    
    }
    
    
    
    /// <summary>
    
    /// 添加数据
    
    /// </summary>
    
    public void Insert()
    
    {
    
    var col = db.GetCollection<Users>();
    
    //或者 
    
    //var col = db.GetCollection("Users");
    
    
    
    Users users = new Users();
    
    users.Name = "xumingxiang";
    
    users.Sex = "man";
    
    col.Insert(users);
    
    }
    
    /// <summary>
    
    /// 更新数据
    
    /// </summary>
    
    public void Update()
    
    {
    
    var col = db.GetCollection<Users>();
    
    //查出Name值为xumingxiang的第一条记录
    
     Users users = col.FindOne(x => x.Name == "xumingxiang");
    
    //或者 
    
    //Users users = col.FindOne(new Document { { "Name", "xumingxiang" } });
    
     users.Sex = "women";
    
    col.Update(users, x => x.Sex == "man");
    
    }
    
    
    
    /// <summary>
    
    /// 删除数据
    
    /// </summary>
    
    public void Delete()
    
    {
    
    var col = db.GetCollection<Users>();
    
    col.Remove(x => x.Sex == "man");
    
    ////或者
    
    ////查出Name值为xumingxiang的第一条记录
    
     //Users users = col.FindOne(x => x.Sex == "man");
    
    //col.Remove(users);
    
    }
    
    
    
    /// <summary>
    
    /// 查询数据
    
    /// </summary>
    
    public void Query()
    
    {
    
    var col = db.GetCollection<Users>();
    
    var query = new Document { { "Name", "xumingxiang" } };
    
    
    
    //查询指定查询条件的全部数据
    
     var result1 = col.Find(query);
    
    //查询指定查询条件的第一条数据
    
     var result2 = col.FindOne(query);
    
    //查询全部集合里的数据
    
     var result3 = col.FindAll();
    
    }
    View Code

     

           封装扩展使用

           1.数据库配置文件

           考虑到一个项目里面可能使用到不同的数据库(比如:普通数据和文件数据等分别存到不同数据库中),也有可能会跨服务器查询,所以这里首先创建一个配置文件帮助类,主要是可以进行多个数据库配置,满足跨服务器,跨数据的需求。

           配置格式如下:

    <?xml version="1.0" encoding="utf-8" ?>
    <ServiceConfig>
      <mongodbs>
        <Item dbName="myDb" hostName="mongodb://127.0.0.1:27017"></Item>
        <Item dbName="myDb1" hostName="mongodb://127.0.0.1:27017"></Item>
        <Item dbName="myDb2" hostName="mongodb://127.0.0.1:27017"></Item>
      </mongodbs>
    </ServiceConfig>

      Xml序列化对象类   

    public class ServiceConfig
        {
            [XmlArray, XmlArrayItem("Item")]
            public List<mongodbConfig> mongodbs { get; set; }
        }
    
        [XmlRoot]
        public class mongodbConfig
        {
            [XmlAttribute("dbName")]
            public string dbName { get; set; }
            [XmlAttribute("hostName")]
            public string hostName { get; set; }
        }
    View Code

       读取配置文件管理类

       public class ManagerConfig
        {
            public static string ConfigPath;
            //加载配置文件
            static ManagerConfig()
            {
                ConfigPath = "./config.xml";
            }
            //xml序列化后的对象
            private static ServiceConfig _settings;
            public static ServiceConfig ServiceSettings
            {
                get
                {
                    return _settings ?? (_settings = Load());
                }
            }
    
            //加载xml序列化为ServiceConfig对象
            static ServiceConfig Load()
            {
                if (File.Exists(ConfigPath))
                {
                    using (FileStream fs = new FileStream(ConfigPath, FileMode.Open))
                    {
                        XmlSerializer xs = new XmlSerializer(typeof(ServiceConfig));
                        //序列化为一个对象
                        _settings = (ServiceConfig)xs.Deserialize(fs);
                    }
                }
                else
                {
                    throw new Exception("数据库配置文件不存在,请检查");
                    //_settings = new ServiceConfig();
                }
    
                return _settings;
            }
        }
    View Code

     

       2.实体通用接口

          mongodb中本身没有自增ID的属性,自带有一个ObjectID,为了统一每个实体对象都有这个ID ,这里建立一个通用接口和一个底层实体基类来进行规范化处理

          实体接口   

    public interface IMongoEntity
        {
            string Id { get; }
        }
    View Code

          底层实体基类   

     public class BaseModel : IMongoEntity
        {
            [BsonIgnore]
            public string Id
            {
                get
                {
                    if (_id == ObjectId.Empty)
                        _id = ObjectId.GenerateNewId(DateTime.Now);
                    return _id.ToString();
                }
            }
            [BsonId]
            private ObjectId _id;
        }
    View Code

         实体类的例子(继承于BaseModel类)     

    public class UserEntity : BaseModel
        {
            public string UserName { get; set; }
    
            public int Num { get; set; }
    
            //MongoDB中存储的时间是标准时间UTC +0:00  (相差了8个小时)
            [BsonDateTimeOptions(Kind = DateTimeKind.Local)]
            public DateTime PostTime { get; set; }
    
        }
    View Code

      3.Mongodb通用帮助基类 (主要类)    

        public class MongodbBase<T> where T : class,IMongoEntity
        {
            protected MongoServer server = null;
            protected MongoDatabase db = null;
            protected MongoCollection<T> collection;
            protected void Init(string DbName)
            {
                var Item = ManagerConfig.ServiceSettings.mongodbs.Where(p => p.dbName == DbName).FirstOrDefault();
                if (Item == null)
                {
                    throw new Exception("不存在数据库为: " + DbName + " 的配置对象,请检查");
                }
                else
                {
                    server = MongoDB.Driver.MongoServer.Create(Item.hostName);
                    db = server.GetDatabase(Item.dbName);
                    collection = db.GetCollection<T>(typeof(T).Name.Replace("Entity", ""));
                }
            }
    
            #region 查询
            /// <summary>
            /// 根据ID获取对象
            /// </summary>
            /// <param name="id"></param>
            /// <returns></returns>
            public T GetModelById(string id)
            {
                return collection.FindOneById(id);
            }
    
            /// <summary>
            /// 获取一条记录(自定义条件)
            /// </summary>
            /// <returns></returns>
            public T FirstOrDefault(Expression<Func<T, bool>> expression)
            {
                MongoDB.Driver.IMongoQuery query = Query<T>.Where(expression);
                return collection.FindOne(query);
            }
    
            /// <summary>
            /// 获取一条记录
            /// </summary>
            /// <returns></returns>
            public T FirstOrDefault()
            {
                return collection.FindAll().FirstOrDefault();
            }
    
            /// <summary>
            /// 获取全部
            /// </summary>
            /// <returns></returns>
            public List<T> FindAll()
            {
                return collection.FindAll().ToList();
            }
    
            /// <summary>
            /// 获取全部(自定义条件)
            /// </summary>
            /// <returns></returns>
            public List<T> FindAll(Expression<Func<T, bool>> expression)
            {
                MongoDB.Driver.IMongoQuery query = Query<T>.Where(expression);
                return collection.Find(query).ToList();
            }
    
            /// <summary>
            /// 根据条件获取数量
            /// </summary>
            /// <param name="expression"></param>
            /// <returns></returns>
            public long GetCount(Expression<Func<T, bool>> expression = null)
            {
                if (expression == null)
                {
                    return collection.Count();
                }
                else
                {
                    return collection.Count(Query<T>.Where(expression));
                }
            }
    
            /// <summary>
            /// 根据ID判断是否存在
            /// </summary>
            /// <param name="id"></param>
            /// <returns></returns>
            public bool Exists(string id)
            {
                return collection.FindOneById(id) != null;
            }
    
            /// <summary>
            /// 分页
            /// </summary>
            /// <param name="PageIndex">总页码</param>
            /// <param name="PageSize">页容量</param>
            /// <param name="RowCounts">总记录数</param>
            /// <param name="expression">条件</param>
            /// <param name="IsAsc">是否是正序</param>
            /// <param name="OrderFiled">排序的字段</param>
            /// <returns></returns>
            public List<T> Page(int PageIndex, int PageSize, out  long RowCounts, Expression<Func<T, bool>> expression = null, bool IsAsc = true, params string[] OrderFiled)
            {
                MongoCursor<T> mongoCursor;
    
                //条件选择
                if (expression != null)
                {
                    RowCounts = collection.Find(Query<T>.Where(expression)).Count();
                    mongoCursor = collection.Find(Query<T>.Where(expression));
                }
                else
                {
                    RowCounts = collection.FindAll().Count();
                    mongoCursor = collection.FindAll();
                }
    
                //排序
                if (OrderFiled != null && OrderFiled.Length > 0)
                {
                    //处理主键字段
                    for (int i = 0; i < OrderFiled.Length; i++)
                    {
                        if (OrderFiled[i].Equals("id", StringComparison.CurrentCultureIgnoreCase))
                        {
                            OrderFiled[i] = "_id";
                        }
                    }
    
                    if (IsAsc)
                    {
                        mongoCursor = mongoCursor.SetSortOrder(SortBy.Ascending(OrderFiled));
                    }
                    else
                    {
                        mongoCursor = mongoCursor.SetSortOrder(SortBy.Descending(OrderFiled));
                    }
                }
    
                return mongoCursor.SetSkip((PageIndex - 1) * PageSize).SetLimit(PageSize).ToList();
            }
    
            #region 效率低,暂时不用
            ///// <summary>
            ///// 分页
            ///// </summary>
            ///// <returns></returns>
            //public List<T> Page(int PageIndex, int PageSize, out  long RowCounts, Expression<Func<T, bool>> expression = null)
            //{
            //    List<T> ret = new List<T>();
            //    IQueryable<T> queryable;
            //    //条件选择
            //    if (expression != null)
            //    {
            //        queryable = collection.Find(Query<T>.Where(expression)).AsQueryable();
            //    }
            //    else
            //    {
            //        queryable = collection.FindAll().AsQueryable();
            //    }
            //    RowCounts = queryable.Count();
            //    ret = queryable.Skip((PageIndex - 1) * PageSize).Take(PageSize).ToList();
            //    return ret;
            //}
    
            ///// <summary>
            ///// 分页
            ///// </summary>
            ///// <typeparam name="TKey"></typeparam>
            ///// <param name="PageIndex"></param>
            ///// <param name="PageSize"></param>
            ///// <param name="RowCounts"></param>
            ///// <param name="expression"></param>
            ///// <param name="orderBy"></param>
            ///// <param name="IsOrder"></param>
            ///// <returns></returns>
            //public List<T> Page<TKey>(int PageIndex, int PageSize, out  long RowCounts, Expression<Func<T, bool>> expression = null, Expression<Func<T, TKey>> orderBy = null, bool IsOrder = true)
            //{
            //    List<T> ret = new List<T>();
            //    IQueryable<T> queryable;
    
            //    //条件选择
            //    if (expression != null)
            //    {
            //        queryable = collection.Find(Query<T>.Where(expression)).AsQueryable();
            //    }
            //    else
            //    {
            //        queryable = collection.FindAll().AsQueryable();
            //    }
            //    //排序
            //    if (orderBy != null)
            //    {
            //        if (IsOrder)
            //        {
            //            queryable = queryable.OrderBy(orderBy);
            //        }
            //        else
            //        {
            //            queryable = queryable.OrderByDescending(orderBy);
            //        }
            //    }
            //    RowCounts = queryable.Count();
            //    ret = queryable.Skip((PageIndex - 1) * PageSize).Take(PageSize).ToList();
            //    return ret;
            //} 
            #endregion
    
            #endregion
    
            #region 删除
    
    
            /// <summary>
            /// 带条件的删除
            /// </summary>
            /// <param name="expression"></param>
            /// <returns></returns>
            public void Delete(Expression<Func<T, bool>> expression)
            {
                MongoDB.Driver.IMongoQuery query = Query<T>.Where(expression);
                var result = collection.Remove(query);
            }
            /// <summary>
            /// 根据模型删除
            /// </summary>
            /// <param name="model"></param>
            public void Delete(T model)
            {
                MongoDB.Driver.IMongoQuery query = Query<T>.Where(p => p.Id == model.Id);
                collection.Remove(query);
            }
    
            /// <summary>
            /// 根据ID删除
            /// </summary>
            /// <param name="Id"></param>
            public void Delete(string Id)
            {
                MongoDB.Driver.IMongoQuery query = Query<T>.Where(p => p.Id == Id);
                collection.Remove(query);
            }
    
            /// <summary>
            /// 全部删除
            /// </summary>
            /// <returns></returns>
            public void DeleteAll()
            {
                var result = collection.RemoveAll();
            }
            #endregion
    
            #region 添加
            /// <summary>
            /// 单模型添加
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            public void Insert(T model)
            {
                var result = collection.Insert<T>(model);
            }
    
            /// <summary>
            /// 批量添加
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            public void InsertBatch(List<T> model)
            {
                collection.InsertBatch<T>(model);
    
            }
            #endregion
    
            #region 修改
            /// <summary>
            /// 修改
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            public void Update(T model)
            {
                var result = collection.Save<T>(model);
            }
    
            /// <summary>
            /// 批量修改
            /// </summary>
            /// <param name="model"></param>
            public void UpdateAll(List<T> model)
            {
                model.ForEach(e => collection.Save<T>(e));
            }
            #endregion
    
        }
    View Code

         4.业务类

          当新建一个表(mongodb里面叫做集合),需要对其进行操作,包括一些业务处理时。首先继承MongodbBase类,然后使用Init方法初始化对象,如下面的UserServcices类

    public class UserServices : MongodbBase<UserEntity>
        {
            public UserServices()
            {
                this.Init("myDb");
            }
    
        }
    View Code

         5.使用    

     [TestClass]
        public class UnitTest1
        {
            Random rd = new Random();
            UserServices ubll = new UserServices();
    
            #region 添加
            [TestMethod]
            public void 添加()
            {
                UserEntity model = new UserEntity();
                model.UserName = "Name" + rd.Next(100, 10000);
                model.Num = rd.Next(100, 10000);
                model.PostTime = DateTime.Now;
                ubll.Insert(model);
    
            }
    
            [TestMethod]
            public void 添加复杂模型()
            {
                ComplexEntity model = new ComplexEntity();
                ComplexServices cbll = new ComplexServices();
                model.Name = "Complex";
                model.Schools = new List<School>();
                model.Schools.Add(new School()
                {
                    Master = new Grade()
                    {
                        Name = "Master"
                    },
                    Name = "School",
                    Students = new List<Student>()
                });
                model.Schools[0].Students.Add(new Student() { Age = 22, Name = "张三" });
                cbll.Insert(model);
            }
    
            [TestMethod]
            public void 批量添加()
            {
                List<UserEntity> Data = new List<UserEntity>();
                for (int i = 0; i < 1000000; i++)
                {
                    UserEntity model = new UserEntity();
                    model.UserName = "Name" + rd.Next(100, 10000);
                    model.Num = rd.Next(100, 10000);
                    model.PostTime = DateTime.Now;
                    Data.Add(model);
                }
                ubll.InsertBatch(Data);
            }
            #endregion
    
            #region 修改
            [TestMethod]
            public void 获取单个对象_修改()
            {
                var model = ubll.FirstOrDefault(p => p.Id != "");
                model.UserName = "new1";
                ubll.Update(model);
            }
            [TestMethod]
            public void 批量修改()
            {
                var model = ubll.FindAll();
                for (int i = 0; i < model.Count; i++)
                {
                    model[i].UserName = "Text";
                }
                ubll.UpdateAll(model);
            }
            #endregion
    
            #region 查询
            [TestMethod]
            public void 获取全部对象()
            {
                var model = ubll.FindAll();
                var count = model.Count;
            }
    
            [TestMethod]
            public void 获取单个对象()
            {
                var model = ubll.FirstOrDefault();
                var count = model.PostTime;
            }
    
            [TestMethod]
            public void 根据ID获取对象()
            {
                var model = ubll.GetModelById("eeef22d6-7ac6-40cd-9312-59ab15fd904a");
            }
    
    
            [TestMethod]
            public void 获取全部对条件象_带条件()
            {
                var model = ubll.FindAll(p => p.UserName.Contains("Name"));
                var count = model.Count;
            }
    
            [TestMethod]
            public void 分页()
            {
    
                long Rows;
                List<UserEntity> pageDate = new List<UserEntity>();
                pageDate = ubll.Page(300, 20, out Rows, p => p.Num > 1500);
                pageDate = ubll.Page(1, 20, out Rows, null, true, "Id");
                pageDate = ubll.Page(1, 20, out Rows, null, true, "Num");
                pageDate = ubll.Page(1, 20, out Rows, p => p.Num > 1500, false, "Id");
    
            }
    
    
            [TestMethod]
            public void 获取数量()
            {
                //不带条件
                var count = ubll.GetCount();
                //带条件
                var count1 = ubll.GetCount(p => p.Num > 5000);
            }
            #endregion
    
            #region 删除
            [TestMethod]
            public void 删除_自定义条件()
            {
                ubll.Delete(p => p.Num >= 2000);
            }
            [TestMethod]
            public void 删除_删除模型()
            {
                var model = ubll.FirstOrDefault();
                if (model != null)
                {
                    ubll.Delete(model);
                }
            }
    
            [TestMethod]
            public void 删除_根据ID删除()
            {
                ubll.Delete("ec45ea8b-a551-46eb-ad58-1b4f5f2aab25");
            }
            [TestMethod]
            public void 删除_删除全部()
            {
                ubll.DeleteAll();
            }
            #endregion
    
            #region 其他
            [TestMethod]
            public void 同时创建两个对象_同一数据库内()
            {
                LogServices Logbll = new LogServices();
    
                UserEntity model = new UserEntity();
                model.UserName = "Name" + rd.Next(100, 10000);
                model.Num = rd.Next(100, 10000);
                model.PostTime = DateTime.Now;
                ubll.Insert(model);
    
                LogEntity log = new LogEntity();
                log.UserName1 = "Name" + rd.Next(100, 10000);
                log.Num1 = rd.Next(100, 10000);
                log.PostTime1 = DateTime.Now;
                Logbll.Insert(log);
    
    
                model.UserName = "Name" + rd.Next(100, 10000);
                model.Num = rd.Next(100, 10000);
                model.PostTime = DateTime.Now;
                ubll.Insert(model);
            }
    
            [TestMethod]
            public void 同时创建两个对象_不同一数据库内()
            {
                Log1Services Logbll = new Log1Services();
    
                UserEntity model = new UserEntity();
                model.UserName = "Name" + rd.Next(100, 10000);
                model.Num = rd.Next(100, 10000);
                model.PostTime = DateTime.Now;
                ubll.Insert(model);
    
                LogEntity log = new LogEntity();
                log.UserName1 = "Name" + rd.Next(100, 10000);
                log.Num1 = rd.Next(100, 10000);
                log.PostTime1 = DateTime.Now;
                Logbll.Insert(log);
    
    
                model.UserName = "Name" + rd.Next(100, 10000);
                model.Num = rd.Next(100, 10000);
                model.PostTime = DateTime.Now;
                ubll.Insert(model);
            }
    
            [TestMethod]
            public void 当指定名称不存在时候()
            {
                ErrorServices error = new ErrorServices();
            }
            #endregion
    
        }
    View Code

      以上就是自己封装的整体逻辑和代码,不过这里面还有一些不明白和不足的地方,这里提出来,希望大神们帮我解答下:

      1.返回值问题

       在添,删,改的使用,根据官网提供的驱动,都有一个WriteConcernResult对象返回,可是在测试中发现,这个返回的对象永远都是null

              

         2.增加ID问题

         mongodb中本身没有自增ID的属性,自带有一个ObjectID,如果我需要一个自增ID,是否是自己建一个ID属性,然后在增加的时候自己控制+1?不过这样是否性能上比较低,还要考虑多线程并发的情况下加锁的问题。所以不知道这块大家是怎么去实现的?

       3.分页效率的问题

        一开始分页我是先将结果转为Queryable,然后在进行操作,这个代码里面有这段,暂时注释掉了,后面再博客园上看到了一个前辈的mongodb分析后,改了下分页的方式,测试过很快,但在带条件获取记录行总数的时候,发现测试300W数据下,获取总数需要600ms的时间,不知道是我方法用错了还是有其他更好的?

       

        

       最后附在几个学习的地址

        mongodb入门:http://www.cnblogs.com/fish-li/archive/2011/06/26/2090800.html

        官网驱动介绍:http://www.cnblogs.com/zhwl/p/3421034.html

        分页优化参考:http://www.cnblogs.com/capqueen/p/MongoDBPagination.html

       源码下载戳这里-》

  • 相关阅读:
    How to Build Office Developer Tools Projects with TFS Team Build 2012
    查看hyper-v主机mac地址
    “Stamping” PDF Files Downloaded from SharePoint 2010
    PostgreSQL体系基本概念
    PostgreSQL 安装
    HDFS+MapReduce+Hive+HBase十分钟快速入门
    光照计算公式
    游戏中的碰撞
    数组
    扑克牌概率
  • 原文地址:https://www.cnblogs.com/qtqq/p/4715120.html
Copyright © 2020-2023  润新知