.net平台的MongoDB使用   前言 MongoDB简介 MongoDB优缺点 MongoDB使用场景 MongoDB安装 MongoDB.Driver的使用 实体更新封装 Lambda表达式更新封装 表达式树的解析 结束 .net平台的MongoDB使用

 

前言

  最近花了点时间玩了下MongoDB.Driver,进行封装了工具库,平常也会经常用到MongoDB,因此写一篇文章梳理知识同时把自己的成果分享给大家。

  本篇会设计到Lambda表达式的解析,有兴趣的同学也看看我之前写的《表达式树的解析》。

  文章最后会给出源码下载地址。

MongoDB简介

  MongoDB是一个基于分布式文件存储的非关系型数据库,相比于其他NoSql它支持复杂的查询。

  文本是类似JSON的BSON格式,BSON是在JSON的基础上进化:更快的遍历、操作更简易、更多的数据类型。因此MongoDB可以存储比较复杂的数据类型,同样也支持建立索引。

  MongoDB的概念有:

  • DataBase(库)
  • Collections(集合),类似于关系型数据库的表
  • Document(文档),类似于关系型数据库的一条数据

  .net平台的MongoDB使用
 
前言
MongoDB简介
MongoDB优缺点
MongoDB使用场景
MongoDB安装
MongoDB.Driver的使用
实体更新封装
Lambda表达式更新封装
表达式树的解析
结束
.net平台的MongoDB使用

MongoDB优缺点

  • 优点

  1. 高效性,内置GridFS,从而达到海量数据存储,并且满足大数据集的快速范围查询。
  2. 高扩展性,分片使MongoDB的有更高的吞吐量,复制使MongoDB更高的可用性。
  3. BSON文档,易于理解、查看,
  4. 免费
  • 缺点

  1. 不支持事务
  2. 不支持表关联
  3. 不耗CPU却耗内存
  4. 没有成熟的管理工具

MongoDB使用场景

  拥有高效的存储的特点,让MongoDB用在操作日志记录是非常流行的做法。

  随着版本的升级提供更加强大的功能,产品逐渐成熟用在主业务也很多,例如电商行业的订单系统与包裹跟踪模块,海量的主订单与订单明细,包裹的状态变更信息。

  然而因为BSON文档的存储方式,使平常的开发的思维模式有所变更。举个栗子,传统用关系型数据库,订单模块就会分主订单表和订单明细表,创建订单就会用事务同时添加两表的数据,查找订单也会通过两表关联查询出来。但是使用MongoDB,主订单表与其明细,将会以一个完整的对象保存为文档。

  也因为不支持事务、表关联的原因,它更加适合用作于一个完整的业务模块。

  .net平台的MongoDB使用
 
前言
MongoDB简介
MongoDB优缺点
MongoDB使用场景
MongoDB安装
MongoDB.Driver的使用
实体更新封装
Lambda表达式更新封装
表达式树的解析
结束
.net平台的MongoDB使用

MongoDB安装

  本来想写的,相应的文章在园子太多了,借用一位仁兄的博文,传送门

  MongoDB下载地址:https://www.mongodb.com/download-center#community

  管理工具:Robomongo,传送门

MongoDB.Driver的使用

  .net平台的MongoDB使用
 
前言
MongoDB简介
MongoDB优缺点
MongoDB使用场景
MongoDB安装
MongoDB.Driver的使用
实体更新封装
Lambda表达式更新封装
表达式树的解析
结束
.net平台的MongoDB使用

  创建一个控制台,到Nuget下载MongoDB.Driver。写入以下代码:

 View Code

  第一个demo:添加数据就完成了。F12可以看到IMongoCollection这个接口,增删改查都有,注意分One和Many。基础的使用就不扯过多,在文章尾部的代码已经提供增删改查的封装。

  增删查的封装相对简单,但是MongoDB.Driver提供的update的稍微比较特殊。通过Builders<T>.Update.Set(_fieldname, value)更新指定字段名,有多个字段名需要修改,就要通过new UpdateDefinitionBuilder<T>().Combine(updateDefinitionList)去完成

.net平台的MongoDB使用
 
前言
MongoDB简介
MongoDB优缺点
MongoDB使用场景
MongoDB安装
MongoDB.Driver的使用
实体更新封装
Lambda表达式更新封装
表达式树的解析
结束
.net平台的MongoDB使用

  然而,这种方式并不适用于我们实际开发,因此需要对Update方法进行 实体更新封装Lambda更新封装

实体更新封装

  通过ID作为过滤条件更新整个实体在实际工作中是常有的。既然通过ID作为条件,那么只能通过UpdateOneAsync进行约束更新一条数据。更新的字段可以通过反射实体对象进行遍历属性。下边是实现代码:

 View Code

Lambda表达式更新封装

  曾经用过其他ORM都清楚Lambda表达式使用是非常频繁的,MongoDB.Driver已经支持Lambda表达式的过滤条件,但没支持部分字段更新,因此由我们自己来写解析。下边是现实代码:

 View Code

表达式树的解析

  对于Lambda表达式的封装,我侧重讲一下。假如有一段这样的更新代码:  

.net平台的MongoDB使用
 
前言
MongoDB简介
MongoDB优缺点
MongoDB使用场景
MongoDB安装
MongoDB.Driver的使用
实体更新封装
Lambda表达式更新封装
表达式树的解析
结束
.net平台的MongoDB使用
new MongoDbService().Update<User>(a => a._id == "d99ce40d7a0b49768b74735b91f2aa75", a => new User
            {
                AddressList = new List<string>
                {
                    "number1",
                    "number2"
                },
                Age = 10,
                BirthDateTime = DateTime.Now,
                Name = "skychen",
                NumList = new List<int>
                {
                    1211,23344
                },
                Sex = Sex.Woman,
                Son = new User
                {
                    Name = "xiaochenpi",
                    Age = 1
                }
            });
.net平台的MongoDB使用
 
前言
MongoDB简介
MongoDB优缺点
MongoDB使用场景
MongoDB安装
MongoDB.Driver的使用
实体更新封装
Lambda表达式更新封装
表达式树的解析
结束
.net平台的MongoDB使用

  那么,我们可以调试监视看看(下图),我们可以得出两个重要信息:

  1.Expression<Func<T, T>>解析出来Body的NodeType是MemberInit

  2.Bindings里有需要修改的字段信息。

.net平台的MongoDB使用
 
前言
MongoDB简介
MongoDB优缺点
MongoDB使用场景
MongoDB安装
MongoDB.Driver的使用
实体更新封装
Lambda表达式更新封装
表达式树的解析
结束
.net平台的MongoDB使用

.net平台的MongoDB使用
 
前言
MongoDB简介
MongoDB优缺点
MongoDB使用场景
MongoDB安装
MongoDB.Driver的使用
实体更新封装
Lambda表达式更新封装
表达式树的解析
结束
.net平台的MongoDB使用

  再调试进去看看Bindings的第一项,我们又可以了解了几个重要信息。

  1.Bindings里的元素是MemberAssignment类型。

  2.Member能取到Name属性,也就是字段名

  3.Expression属性,使用 Expression.Lambda,进行Compile().Invoke()就能得到我们需要的值。

  fileName和Value都能取到了,那么更新自然能解决了。

.net平台的MongoDB使用
 
前言
MongoDB简介
MongoDB优缺点
MongoDB使用场景
MongoDB安装
MongoDB.Driver的使用
实体更新封装
Lambda表达式更新封装
表达式树的解析
结束
.net平台的MongoDB使用

  上图是源码的部分核心代码,奇怪的是,我并没有在VisitMemberInit里进行遍历Bindings后进行Update.Set,而是将item的Expression属性再一次访问。那是因为我需要针对不同的数据类型进行处理。例如:

  常量,我可以定义一个object value进行去接收,如果遇到枚举我需要强转成整型。

  集合与数组,假如草率的使用object类型,object value = Expression.Lambda<Func<object>>(node).Compile().Invoke(),那么更新到MongoDB里就会有bug,奇怪的_t,_v就会出现。以此我需要定义为IList才能解决这个问题。

  此外,工作中还会遇到金额或者数量自增的情况。Amount = a.Amount+9.9M,Count =a.Count-1。 MongoDB.Driver提供了Builders<T>.Update.Inc方法,因此重写二元表达式进行封装。

.net平台的MongoDB使用
 
前言
MongoDB简介
MongoDB优缺点
MongoDB使用场景
MongoDB安装
MongoDB.Driver的使用
实体更新封装
Lambda表达式更新封装
表达式树的解析
结束
.net平台的MongoDB使用

结束

  不知道有多少朋友直接拖到文章尾部直接下载源码的。。。。。。

  如果对您有用,麻烦您推荐一下。

  此外还要感谢广州赛酷比科技物流组的杜小非同志,率先做了我的小白鼠给我提出了可贵的BUG,不然我还真不敢放出源码。

  如果有什么问题和建议,可以在下方评论,我会及时回复。

  双手奉上源码:https://github.com/SkyChenSky/Framework.MongoDB.git

 

前言

  最近花了点时间玩了下MongoDB.Driver,进行封装了工具库,平常也会经常用到MongoDB,因此写一篇文章梳理知识同时把自己的成果分享给大家。

  本篇会设计到Lambda表达式的解析,有兴趣的同学也看看我之前写的《表达式树的解析》。

  文章最后会给出源码下载地址。

MongoDB简介

  MongoDB是一个基于分布式文件存储的非关系型数据库,相比于其他NoSql它支持复杂的查询。

  文本是类似JSON的BSON格式,BSON是在JSON的基础上进化:更快的遍历、操作更简易、更多的数据类型。因此MongoDB可以存储比较复杂的数据类型,同样也支持建立索引。

  MongoDB的概念有:

  • DataBase(库)
  • Collections(集合),类似于关系型数据库的表
  • Document(文档),类似于关系型数据库的一条数据

  .net平台的MongoDB使用
 
前言
MongoDB简介
MongoDB优缺点
MongoDB使用场景
MongoDB安装
MongoDB.Driver的使用
实体更新封装
Lambda表达式更新封装
表达式树的解析
结束
.net平台的MongoDB使用

MongoDB优缺点

  • 优点

  1. 高效性,内置GridFS,从而达到海量数据存储,并且满足大数据集的快速范围查询。
  2. 高扩展性,分片使MongoDB的有更高的吞吐量,复制使MongoDB更高的可用性。
  3. BSON文档,易于理解、查看,
  4. 免费
  • 缺点

  1. 不支持事务
  2. 不支持表关联
  3. 不耗CPU却耗内存
  4. 没有成熟的管理工具

MongoDB使用场景

  拥有高效的存储的特点,让MongoDB用在操作日志记录是非常流行的做法。

  随着版本的升级提供更加强大的功能,产品逐渐成熟用在主业务也很多,例如电商行业的订单系统与包裹跟踪模块,海量的主订单与订单明细,包裹的状态变更信息。

  然而因为BSON文档的存储方式,使平常的开发的思维模式有所变更。举个栗子,传统用关系型数据库,订单模块就会分主订单表和订单明细表,创建订单就会用事务同时添加两表的数据,查找订单也会通过两表关联查询出来。但是使用MongoDB,主订单表与其明细,将会以一个完整的对象保存为文档。

  也因为不支持事务、表关联的原因,它更加适合用作于一个完整的业务模块。

  .net平台的MongoDB使用
 
前言
MongoDB简介
MongoDB优缺点
MongoDB使用场景
MongoDB安装
MongoDB.Driver的使用
实体更新封装
Lambda表达式更新封装
表达式树的解析
结束
.net平台的MongoDB使用

MongoDB安装

  本来想写的,相应的文章在园子太多了,借用一位仁兄的博文,传送门

  MongoDB下载地址:https://www.mongodb.com/download-center#community

  管理工具:Robomongo,传送门

MongoDB.Driver的使用

  .net平台的MongoDB使用
 
前言
MongoDB简介
MongoDB优缺点
MongoDB使用场景
MongoDB安装
MongoDB.Driver的使用
实体更新封装
Lambda表达式更新封装
表达式树的解析
结束
.net平台的MongoDB使用

  创建一个控制台,到Nuget下载MongoDB.Driver。写入以下代码:

 View Code

  第一个demo:添加数据就完成了。F12可以看到IMongoCollection这个接口,增删改查都有,注意分One和Many。基础的使用就不扯过多,在文章尾部的代码已经提供增删改查的封装。

  增删查的封装相对简单,但是MongoDB.Driver提供的update的稍微比较特殊。通过Builders<T>.Update.Set(_fieldname, value)更新指定字段名,有多个字段名需要修改,就要通过new UpdateDefinitionBuilder<T>().Combine(updateDefinitionList)去完成

.net平台的MongoDB使用
 
前言
MongoDB简介
MongoDB优缺点
MongoDB使用场景
MongoDB安装
MongoDB.Driver的使用
实体更新封装
Lambda表达式更新封装
表达式树的解析
结束
.net平台的MongoDB使用

  然而,这种方式并不适用于我们实际开发,因此需要对Update方法进行 实体更新封装Lambda更新封装

实体更新封装

  通过ID作为过滤条件更新整个实体在实际工作中是常有的。既然通过ID作为条件,那么只能通过UpdateOneAsync进行约束更新一条数据。更新的字段可以通过反射实体对象进行遍历属性。下边是实现代码:

 View Code

Lambda表达式更新封装

  曾经用过其他ORM都清楚Lambda表达式使用是非常频繁的,MongoDB.Driver已经支持Lambda表达式的过滤条件,但没支持部分字段更新,因此由我们自己来写解析。下边是现实代码:

 View Code

表达式树的解析

  对于Lambda表达式的封装,我侧重讲一下。假如有一段这样的更新代码:  

.net平台的MongoDB使用
 
前言
MongoDB简介
MongoDB优缺点
MongoDB使用场景
MongoDB安装
MongoDB.Driver的使用
实体更新封装
Lambda表达式更新封装
表达式树的解析
结束
.net平台的MongoDB使用
new MongoDbService().Update<User>(a => a._id == "d99ce40d7a0b49768b74735b91f2aa75", a => new User
            {
                AddressList = new List<string>
                {
                    "number1",
                    "number2"
                },
                Age = 10,
                BirthDateTime = DateTime.Now,
                Name = "skychen",
                NumList = new List<int>
                {
                    1211,23344
                },
                Sex = Sex.Woman,
                Son = new User
                {
                    Name = "xiaochenpi",
                    Age = 1
                }
            });
.net平台的MongoDB使用
 
前言
MongoDB简介
MongoDB优缺点
MongoDB使用场景
MongoDB安装
MongoDB.Driver的使用
实体更新封装
Lambda表达式更新封装
表达式树的解析
结束
.net平台的MongoDB使用

  那么,我们可以调试监视看看(下图),我们可以得出两个重要信息:

  1.Expression<Func<T, T>>解析出来Body的NodeType是MemberInit

  2.Bindings里有需要修改的字段信息。

.net平台的MongoDB使用
 
前言
MongoDB简介
MongoDB优缺点
MongoDB使用场景
MongoDB安装
MongoDB.Driver的使用
实体更新封装
Lambda表达式更新封装
表达式树的解析
结束
.net平台的MongoDB使用

.net平台的MongoDB使用
 
前言
MongoDB简介
MongoDB优缺点
MongoDB使用场景
MongoDB安装
MongoDB.Driver的使用
实体更新封装
Lambda表达式更新封装
表达式树的解析
结束
.net平台的MongoDB使用

  再调试进去看看Bindings的第一项,我们又可以了解了几个重要信息。

  1.Bindings里的元素是MemberAssignment类型。

  2.Member能取到Name属性,也就是字段名

  3.Expression属性,使用 Expression.Lambda,进行Compile().Invoke()就能得到我们需要的值。

  fileName和Value都能取到了,那么更新自然能解决了。

.net平台的MongoDB使用
 
前言
MongoDB简介
MongoDB优缺点
MongoDB使用场景
MongoDB安装
MongoDB.Driver的使用
实体更新封装
Lambda表达式更新封装
表达式树的解析
结束
.net平台的MongoDB使用

  上图是源码的部分核心代码,奇怪的是,我并没有在VisitMemberInit里进行遍历Bindings后进行Update.Set,而是将item的Expression属性再一次访问。那是因为我需要针对不同的数据类型进行处理。例如:

  常量,我可以定义一个object value进行去接收,如果遇到枚举我需要强转成整型。

  集合与数组,假如草率的使用object类型,object value = Expression.Lambda<Func<object>>(node).Compile().Invoke(),那么更新到MongoDB里就会有bug,奇怪的_t,_v就会出现。以此我需要定义为IList才能解决这个问题。

  此外,工作中还会遇到金额或者数量自增的情况。Amount = a.Amount+9.9M,Count =a.Count-1。 MongoDB.Driver提供了Builders<T>.Update.Inc方法,因此重写二元表达式进行封装。

.net平台的MongoDB使用
 
前言
MongoDB简介
MongoDB优缺点
MongoDB使用场景
MongoDB安装
MongoDB.Driver的使用
实体更新封装
Lambda表达式更新封装
表达式树的解析
结束
.net平台的MongoDB使用

结束

  不知道有多少朋友直接拖到文章尾部直接下载源码的。。。。。。

  如果对您有用,麻烦您推荐一下。

  此外还要感谢广州赛酷比科技物流组的杜小非同志,率先做了我的小白鼠给我提出了可贵的BUG,不然我还真不敢放出源码。

  如果有什么问题和建议,可以在下方评论,我会及时回复。

  双手奉上源码:https://github.com/SkyChenSky/Framework.MongoDB.git