【MongoDB】递归获取字段更新表达式,更新复杂数据类型对象
在实际更新Mongo对象时发现,原有的更新代码无法更新复杂的数据类型对象。恰好看到张占岭老师有对该方法做相关的改进,因此全抄了下来。
总的核心思想就是运用反射与递归,对对象属性一层一层挖掘下去,循环创建父类及之类的更新表达式。
相关代码如下:
#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);elseGenerateRecursion(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);elseGenerateRecursion(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));elsefieldList.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
View Code
在实际应用过程中,有几点要注意一下:
1.在对象创建时,就要将对象中的数组属性初始化,否则在更新时无法插入子项。
public class Users : MongoObj
{public Users() {Subs = new List<Sub>();Spell = new List<int>();}public string ObjectId_id { get; set; }public string Name { get; set; }public string Sex { set; get; }public List<int> Spell { get; set; }public List<Sub> Subs { get; set; }
}
2.如果数组是一个复杂对象数据,那么要给对象添加一个_id,并且在对象初始化时就给_id赋值。
public class Sub {public Sub() { _id = MongoDB.Bson.ObjectId.GenerateNewId().ToString();}public string _id { get; set; }public string aa {get;set;}public string bb{get;set;} }
3.实际使用的时候发现无法对数组的子项做删除。
比如删除Subs中的第一个子项后,再到mongo里面查询,发现第一个子项仍然存在。
暂时还没有好的解决方法,如果有涉及到数组子项的删除操作,都是将整个对象删掉,然后再重新插入,简单粗暴。
转载于:https://www.cnblogs.com/nonkicat/p/5581726.html
【MongoDB】递归获取字段更新表达式,更新复杂数据类型对象相关推荐
- ONLYOFFICE文档V7.2现已发布————插件市场、实时查看器、连写、全新表单字段、UI 更新等
ONLYOFFICE文档V7.2现已发布 ----插件市场.实时查看器.连写.全新表单字段.UI 更新等 我们已在最新版本的在线编辑器中提供了多种实用性改进,比如:轻松的插件安装流程.实时查看器.支持 ...
- mybatis动态查询字段、动态更新字段
一.动态查询字段并返回list 接收的对象 @Data public class TableFieldOutput implements Serializable {private static fi ...
- MongoDB中的子文档批量更新
Mongodb 3.6版本的福利好吧! 谢谢观看,转载请标注来源Thanks!©PerfumerKarma 官网文档地址: https://docs.mongodb.com/manual/refere ...
- SAP QM 物料主数据QM视图里字段MARC-INSMK的更新
SAP QM 物料主数据QM视图里字段MARC-INSMK的更新 在物料主数据的质量管理视图,有一个字段'Post to Insp.stock'(MARC-INSMK)的.该字段在启用了QM模块之后, ...
- mysql触发器 当记录的指定字段发生变化时,更新表中的另外一个字段,或者更新另外一张关联表中关联记录的字段...
2019独角兽企业重金招聘Python工程师标准>>> 注意:语句中出现的old,new,now(),都为数据库自带的关键字,此处不做解释. 两种情况: 第一种:一张表中,更新某条记 ...
- 来自网页的消息服务器繁处理忙,EventSource 对象用于接收服务器发送事件通知,是网页自动获取来自服务器的更新...
//--------------------------------客户端代码----------------------------- if(typeof(EventSource) !== &quo ...
- #Oracle Clob类型字段插入与更新
Oracle Clob类型字段插入与更新 (一)在oracle中,有一种类型叫做大对象类型,分为二进制的blob和字符型的char类型,用于存储字符串超过4000(varchar2的长度限制是4000 ...
- mongodb @aggregation 返回字段映射不上_MongoDB---基于分布式文件存储的数据库(二)...
MongoDB基础入门到高级进阶视频教程 [MongoDB] 六.Document 操作 在MongoDB中文档是指多个键及其关联的值有序地放置在一起就是文档,其实指的就是数据,也是我们平时操作最多的 ...
- mongodb 输出数组字段_MongoDb文档操作、索引操作
学习主题:MongoDb 学习目标: 掌握mongodb文档的更新 掌握mongodb文档的删除 掌握mongodb文档的查找 掌握mongodb文档的条件操作符 掌握mongodb中的索引操作 Mo ...
最新文章
- 2021年人工智能数据采集标注行业四大趋势预测
- while 小项目练习
- VS2013的项目转到VS2010需要修改的
- 【Flutter】Flutter 混合开发 ( 关联 Android 工程与 Flutter 工程 | 安卓页面中嵌入 Flutter 页面 | 安卓中启动 Flutter 页面 )
- SAP修改科目为未清项管理和行项目显示
- mysql merge 分区_mysql merge 分区
- Redhat安装tftp的方法
- ASP.NET Core技术研究-全面认识Web服务器Kestrel
- windows服务器新建管理员用户_用户和组管理
- 01Python可视化开发环境之Pycharm+Anaconda3安装配置详细步骤
- SaaS服务商盘点之ERP篇
- 节约里程法求解CVRP问题
- Linux中运行shell脚本的几种方式及其区别(source . ./myscript.sh sh myscript.sh)
- Frequency domain enhancement
- 西南大学网络作业答案计算机,2019西南大学继续教育学院《计算机基础》作业答案...
- 苹果电脑破音的解决办法
- 【CVPR2020视频超分辨率】Zooming Slow-Mo: Fast and Accurate One-Stage Space-Time Video Super-Resolution 阅读笔记
- 【coolshell】开源中最好的Web开发的资源
- 晨枫U盘维护工具的ISOLINUX模式可加载磁盘映像的探索及USB-ROM引导后安装系统的相关问题
- 4~20mA电流环采集电路
热门文章
- 如何利用python在一个wen'dang'li_如何利用Python网络爬虫给自己跟朋友来一份穷游攻略!走到哪里穷到哪里的哦!...
- 如何保证消息不被重复消费~~~~~(如何保证消息队列的幂等性)
- linux dd安装系统,通过DD命令安装Windows,并介绍几款DD镜像包
- 计算机基础:存储系统知识笔记(二)
- 手机:导致手机发烫的原因有哪些?
- 在程序员面前千万不要说这9句话,我一个同事就死的很惨!
- 程序员如何优雅度过一生的15个建议
- ip访问php $_files空,PHP中表单没有问题但$_FILES为空怎么办?
- 高考填报志愿计算机操作技巧,高考志愿填报技巧经验
- 克服浮躁_设计思维:您克服并赢得低迷的最终工具。