设为首页 收藏本站
查看: 1057|回复: 0

[经验分享] .net平台的MongoDB使用

[复制链接]

尚未签到

发表于 2017-12-14 21:38:28 | 显示全部楼层 |阅读模式
前言
  最近花了点时间玩了下MongoDB.Driver,进行封装了工具库,平常也会经常用到MongoDB,因此写一篇文章梳理知识同时把自己的成果分享给大家。
  本篇会设计到Lambda表达式的解析,有兴趣的同学也看看我之前写的《表达式树的解析》。
  文章最后会给出源码下载地址。

MongoDB简介
  MongoDB是一个基于分布式文件存储的非关系型数据库,相比于其他NoSql它支持复杂的查询。
  文本是类似JSON的BSON格式,BSON是在JSON的基础上进化:更快的遍历、操作更简易、更多的数据类型。因此MongoDB可以存储比较复杂的数据类型,同样也支持建立索引。
  MongoDB的概念有:


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


MongoDB优缺点



  • 优点


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



  • 缺点


  • 不支持事务
  • 不支持表关联
  • 不耗CPU却耗内存
  • 没有成熟的管理工具

MongoDB使用场景
  拥有高效的存储的特点,让MongoDB用在操作日志记录是非常流行的做法。
  随着版本的升级提供更加强大的功能,产品逐渐成熟用在主业务也很多,例如电商行业的订单系统与包裹跟踪模块,海量的主订单与订单明细,包裹的状态变更信息。
  然而因为BSON文档的存储方式,使平常的开发的思维模式有所变更。举个栗子,传统用关系型数据库,订单模块就会分主订单表和订单明细表,创建订单就会用事务同时添加两表的数据,查找订单也会通过两表关联查询出来。但是使用MongoDB,主订单表与其明细,将会以一个完整的对象保存为文档。
  也因为不支持事务、表关联的原因,它更加适合用作于一个完整的业务模块。
DSC0001.png


MongoDB安装
  本来想写的,相应的文章在园子太多了,借用一位仁兄的博文,传送门
  MongoDB下载地址:https://www.mongodb.com/download-center#community
  管理工具:Robomongo,传送门

MongoDB.Driver的使用
DSC0002.png

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


DSC0003.gif View Code  第一个demo:添加数据就完成了。F12可以看到IMongoCollection这个接口,增删改查都有,注意分One和Many。基础的使用就不扯过多,在文章尾部的代码已经提供增删改查的封装。
  增删查的封装相对简单,但是MongoDB.Driver提供的update的稍微比较特殊。通过Builders<T>.Update.Set(_fieldname, value)更新指定字段名,有多个字段名需要修改,就要通过new UpdateDefinitionBuilder<T>().Combine(updateDefinitionList)去完成
DSC0004.png

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

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


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


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




DSC0005.gif
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
}
});

  那么,我们可以调试监视看看(下图),我们可以得出两个重要信息:
  1.Expression<Func<T, T>>解析出来Body的NodeType是MemberInit
  2.Bindings里有需要修改的字段信息。
DSC0006.png

DSC0007.png

  再调试进去看看Bindings的第一项,我们又可以了解了几个重要信息。
  1.Bindings里的元素是MemberAssignment类型。
  2.Member能取到Name属性,也就是字段名
  3.Expression属性,使用 Expression.Lambda,进行Compile().Invoke()就能得到我们需要的值。
  fileName和Value都能取到了,那么更新自然能解决了。
DSC0008.jpg

  上图是源码的部分核心代码,奇怪的是,我并没有在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方法,因此重写二元表达式进行封装。
DSC0009.png


结束
  不知道有多少朋友直接拖到文章尾部直接下载源码的。。。。。。
  如果对您有用,麻烦您推荐一下。
  此外还要感谢广州赛酷比科技物流组的杜小非同志,率先做了我的小白鼠给我提出了可贵的BUG,不然我还真不敢放出源码。
  如果有什么问题和建议,可以在下方评论,我会及时回复。
  双手奉上源码:https://github.com/SkyChenSky/Framework.MongoDB.git






原文:
.net平台的MongoDB使用

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-424167-1-1.html 上篇帖子: mongodb 权限设置 下篇帖子: MongoDb 命令查询所有数据库列表
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表