MongoDB学习笔记~官方驱动嵌套数组对象的更新
对于数组对象mongodb本身是支持的,不过对于数组的更新,mongodb的Csharp驱动目前只支持一级,即你的对象里包含数组,而数组又包括数组,这表示两层,这在更新子数组时,Csharp驱动是不支持的,今天要说的就是如何让它支持子数组的更新,下面是我给出的数据结构
在Mongodb的Csharp驱动里,一般的更新方法如下
update = new UpdateDocument {{ "$set", new BsonDocument("OrderList.$.UserName","占占的订单") }}; mongoRepository.Collection.Update(query, update);
上面代码可以很快速的将指定的二级数组OrderList里的UserName字段更新,而如果你要更新OrderDetail就没那么容易了,Csharp驱支目前是不支持的,当然你肯定会照着葫芦画飘,但结果是失败的,就像下面的代码(失败,只有既望新版驱动了)
update = new UpdateDocument {{ "$set", new BsonDocument("OrderList.$.OrderDetail.ProductName","占占") }}; mongoRepository.Collection.Update(query, update);
结果是OrderDetail的ProductName没有发生任何变化,呵呵。
去找原因,去找资料,还好,找到了一个不错的说法,即要想更新数组内的数组,需要将对上级数据进行定位,如OrderList.0.OrderDetail,这表示下标为0的OrderList数组元素(一个实体)下的OrderDetail数组对象,当然这个下标可不是那么轻易能得到的,
我们需要对数组进行遍历,找到满足条件的后,进行break即可。
var mongoRepository = new MongoDB.Data.Core.MongoOfficialRepository<Person>(); var query = Query.EQ("OrderList._id", twoID); var oo = mongoRepository.Collection.Find(query).FirstOrDefault(); var update = new UpdateDocument(); bool isExit = false; for (int j = 0; j < oo.OrderList.Count; j++) { var od = oo.OrderList[j].OrderDetail; oo.OrderList[j].UserName = "大占占改呀"; for (int i = 0; i < od.Count; i++) { if (od[i].Id == threeID) { od[i].ProductName = "大占占修改了订单21"; #region 先pull,再push //update = new UpdateDocument {{ "$pull", // new BsonDocument("OrderList."+j+".OrderDetail", // new BsonDocument("_id",threeID)) // }}; //mongoRepository.Collection.Update(query1, update); //update = new UpdateDocument {{ "$push", // new BsonDocument("OrderList."+j+".OrderDetail", // new BsonDocument(od[i].ToDictionary())) // }}; //mongoRepository.Collection.Update(query1, update); #endregion #region 直接set update = new UpdateDocument {{ "$set", new BsonDocument("OrderList.$.UserName",oo.OrderList[j].UserName) }}; mongoRepository.Collection.Update(query, update); update = new UpdateDocument {{ "$set", new BsonDocument("OrderList."+j+".OrderDetail."+i, new BsonDocument(od[i].ToDictionary())) }}; mongoRepository.Collection.Update(query, update); #endregion isExit = true; break; } } if (isExit) break; }
上面的代码,我们看到了有两种更新集合的方法,$pull和$push方法及$set方法,大家可以根据喜好进行选择,都可以实现我们的目的,ToDictionary是我封装的方法,意思是将类对象里的属性转换为字典,并做了mongodb的_id主键的处理,代码如下
/// <summary> /// 将对象属性转换为字典 /// </summary> /// <param name="o"></param> /// <returns></returns> public static Dictionary<String, Object> ToDictionary(this object o) { Dictionary<String, Object> map = new Dictionary<string, object>(); Type t = o.GetType(); PropertyInfo[] pi = t.GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (PropertyInfo p in pi) { MethodInfo mi = p.GetGetMethod(); if (mi != null && mi.IsPublic) { if (p.Name == "Id") map.Add("_id", mi.Invoke(o, new Object[] { })); else map.Add(p.Name, mi.Invoke(o, new Object[] { })); } } return map; } }
对于mongodb的探索,还在继续...
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
2012-08-03 第一回 要想知道为什么抽象出基类,应该先对基类有一个比较明确的认识
2011-08-03 MVC工作中的笔记~2(架构师是一步一步练成的)
2011-08-03 MVC工作中的笔记~1(架构师是一步一步练成的)
2011-08-03 数据结构~二叉树
2011-08-03 数据结构~线性表
2011-08-03 数据结构~链表