回到目录

在对MongoDB进行封装后,对于Update更新对象里的集合属性时出现了一个现象,让人感到很恶心,人家更新前是个美丽的Array,但是更新之后集合对象变成了键值对,键是集合的类型名称,值是真实的数组值,哈哈,这个问题起初困扰了我很久,今天终于豁然开朗了,原来是Update方法的问题,呵呵!

看原来的值

看更新后的变质的值

再看看我们的Update方法

    public Task UpdateAsync(TEntity item){var query = new QueryDocument("_id", typeof(TEntity).GetProperty(EntityKey).GetValue(item).ToString());var fieldList = new List<UpdateDefinition<TEntity>>();foreach (var property in typeof(TEntity).GetProperties(BindingFlags.Instance | BindingFlags.Public)){if (property.Name != EntityKey)//更新集中不能有实体键_id
                {fieldList.Add(Builders<TEntity>.Update.Set(property.Name, property.GetValue(item)));}}return ForWait(() => _table.UpdateOneAsync(query, Builders<TEntity>.Update.Combine(fieldList)));}

确实没看出什么问题来,但最后它生成的代码是以_t和_v为键值的值,出现这种情况的原因是你的代码没有被mongo识别,就像之前我们为mongo传decimal类型的数据一样,它也会出现同样的情况。

解决方法

将复杂类型进行拆封和组装,让它被mongo所认识,这样update操作就可以按着我们预想的完成了,值得注意的是,如果你的对象里有复杂类型,如Person类里有Address类型,那么在赋值时我们拼成以下这样

Address.City="北京"

而如果你的对象里属性为集合类型,那就更麻烦一些,除了做上面的拆封外,还要关注它的索引号,如Person类里有AddList集合属性,那么在赋值时我们拼成以下这样

AddList.0.City="北京"

下面公开大叔的Update代码

        public Task UpdateAsync(TEntity item){var query = new QueryDocument("_id", typeof(TEntity).GetProperty(EntityKey).GetValue(item).ToString());var fieldList = new List<UpdateDefinition<TEntity>>();foreach (var property in typeof(TEntity).GetProperties(BindingFlags.Instance | BindingFlags.Public)){//非空的复杂类型if (property.PropertyType.IsClass && property.PropertyType != typeof(string) && property.GetValue(item) != null){if (typeof(IList).IsAssignableFrom(property.PropertyType)){#region 集合类型foreach (var sub in property.PropertyType.GetProperties(BindingFlags.Instance | BindingFlags.Public)){if (sub.PropertyType.IsClass && sub.PropertyType != typeof(string)){var arr = property.GetValue(item) as IList;if (arr != null && arr.Count > 0){for (int s = 0; s < arr.Count; s++){foreach (var subInner in sub.PropertyType.GetProperties(BindingFlags.Instance | BindingFlags.Public)){//propertyName.index.innerPropertyNamefieldList.Add(Builders<TEntity>.Update.Set(property.Name + "."+ s + "." + subInner.Name, subInner.GetValue(arr[s])));}}}}}#endregion}else{#region 实体类型//复杂类型,导航属性,类对象和集合对象 foreach (var sub in property.PropertyType.GetProperties(BindingFlags.Instance | BindingFlags.Public)){fieldList.Add(Builders<TEntity>.Update.Set(property.Name + "." + sub.Name, sub.GetValue(property.GetValue(item))));}#endregion}}else //简单类型
                {if (property.Name != EntityKey)//更新集中不能有实体键_id
                    {fieldList.Add(Builders<TEntity>.Update.Set(property.Name, property.GetValue(item)));}}}return ForWait(() => _table.UpdateOneAsync(query, Builders<TEntity>.Update.Combine(fieldList)));}

希望本文章对使用MongoDB的学生来说有所帮助!

回到目录

转载于:https://www.cnblogs.com/lori/p/4538550.html

MongoDB学习笔记~Update方法更新集合属性后的怪问题相关推荐

  1. MongoDB学习笔记~对集合属性的操作

    $unset清除元素 请注意在单个数组元素上使用$unset的结果可能与你设想的不一样.其结果只是将元素的值设置为null,而非删除整个元素.要想彻底删除某个数组元素,可以用$pull 和$pop操作 ...

  2. VB.NET学习笔记:ADO.NET操作ACCESS数据库——OleDbDataAdapter的Update方法更新数据库的秘密(行状态RowState和行版本 DataRowVersion)

    在<数据集DataSet数据管理(DataAdapter查询更新数据库)>一文中提到可以使用OleDbDataAdapter对象的Update方法还可将对 DataSet 所做的更改解析回 ...

  3. MongoDB学习笔记(七)——MongoDB shell方法汇总

    在写前面的博文的时候,我发现MongoDB shell提供了很多方法,其中MongoDB的很多方法也在其中,下面是我从MongoDB官网上查到的所有MongoDB shell的所有方法,当然,我不会对 ...

  4. MongoDB学习笔记(入门)

    MongoDB学习笔记(入门) 一.文档的注意事项: 1.  键值对是有序的,如:{ "name" : "stephen", "genda" ...

  5. PHP操作MongoDB学习笔记

    PHP操作MongoDB技術總結 <?php /** * PHP操作MongoDB学习笔记 */ //************************* //**   连接MongoDB数据库  ...

  6. 非关系型数据库MongoDB学习笔记

    MongoDB学习笔记   --周灿 创建数据库 use "databasename" 查看数据库 show dbs 给指定数据库添加集合和插入记录 db.集合名.insert({ ...

  7. Java开发面试高频考点学习笔记(每日更新)

    Java开发面试高频考点学习笔记(每日更新) 1.深拷贝和浅拷贝 2.接口和抽象类的区别 3.java的内存是怎么分配的 4.java中的泛型是什么?类型擦除是什么? 5.Java中的反射是什么 6. ...

  8. Go语言开发学习笔记(持续更新中)

    Go语言开发学习笔记(持续更新中) 仅供自我学习 更好的文档请选择下方 https://studygolang.com/pkgdoc https://www.topgoer.com/go%E5%9F% ...

  9. MongoDB学习笔记总结(含报错、问题、技巧)

    环境 OS:Ubuntu20.04 MongoDB:v5.0.2 一.MongoDB简介 MongoDB是一个开源文档数据库,提供高性能,高可用性和自动扩展,旨在为WEB应用提供可扩展的高性能数据存储 ...

最新文章

  1. Ubuntu Linux 安装后,建立嵌入式开发环境
  2. 你以为没有CAD的前辈们画不出复杂的图纸?
  3. substringToIndex substringFromIndex
  4. HDU5971【瞎搞】
  5. 吴裕雄--天生自然 物理学习与探索笔记:磁场、磁感线以及电磁感应、回旋加速器...
  6. 20200721:每日一题之不同的二叉搜索树 II(leetcode95)
  7. 十分钟带你理解Kubernetes核心概念
  8. ARM版Win11系统(intel版Win10/11系统)
  9. 基础:新建个maven项目
  10. 已知两点坐标,求两点连成的直线中的某一点坐标
  11. 5个Web前端开发软件,零基础入门完全够用了!
  12. 服务器上qq打不开网页,能上qq打不开网页的解决方法
  13. 上研究生学计算机去河大学校好不好,河南大学研究生,河南大学研究生值得读吗?...
  14. 在控制台打印不完整的解决问题
  15. 【电气设计】理论知识学习(持续更新中...)
  16. 漏洞分析---关于OpenSSL“心脏出血”漏洞的分析
  17. Unix 操作系统背后的女程序员 Lorinda Cherry 去世,享年 78 岁
  18. 【BZOJ4552】【TJOI2016HEOI2016】排序(线段树、二分)
  19. 计算两个矩阵乘积(两种方式实现)(C语言)
  20. 凯撒密码c语言公式原理,凯撒密码 C语言实现.pdf

热门文章

  1. java 静态 编译_Java中的动态和静态编译实例详解
  2. FPGA之道(55)状态机的HDL模板
  3. IC/FPGA校招笔试题分析(二)任意切换的时钟分频电路
  4. 【 MATLAB 】范数的必备基础知识
  5. Spring|AOP
  6. hdoj1175 连连看(dfs+剪枝)
  7. 64位环境编译DiskSim 4.0
  8. EDM营销中HTML邮件设计的技巧
  9. OSI 七层参考模型
  10. vivado使用自带IP核和创建自己定义的IP核