回到目录
请注意在单个数组元素上使用$unset的结果可能与你设想的不一样。其结果只是将元素的值设置为null,而非删除整个元素。要想彻底删除某个数组元素,可以用$pull 和$pop操作符。
该两者的功能都是给数组添加一个值。但是两者之间有区别,$addToSet要添加的值如果不存在才进行添加操作,但是push只添加一个值;例如:
tags = [“zzl”,”dudu”]
如果执行db.collection.update({},{$push:{tag:"laozhao"}}) 结果就是 [“laozhao”,”zzl”,“dudu”]
如果执行db.collection.update({},{$addToSet:{tag:"zzl"}}) 结果不变
对于Update.Combine我们可以把需要更新的字段合并到列表List<UpdateDefinition<T>>()中,最后一起进行更新,而这对于集合属性来说,需要注意一下,我们需要为 集合属性元素使用PushEach进行添加,而不是Push ,因为使用Push会将前一个元素覆盖掉,而只保留最后的元素(集合里的),所以需要使用PushEach来代替它,代码如下:
[TestMethod] public void Push() { var filter = Builders<Dog>.Filter.Eq(i => i.Id, "5850b0bdebb91a3184f90d3d"); //更新所需要的字段 var updateList = new List<UpdateDefinition<Dog>>(); //更新需要集合类型的字段 var dogHistoryList = new List<DogHistory>(); //添加元素到集合属性 dogHistoryList.Add(new DogHistory { HistoryName = "四虎子3", IsHealth = false, Adderss = new Adderss("广东", "深圳", "沿海") }); dogHistoryList.Add(new DogHistory { HistoryName = "四虎子4", IsHealth = false, Adderss = new Adderss("广东", "深圳", "沿海") }); //将需要更新集合对象添加到updateList里 updateList.Add(Builders<Dog>.Update.PushEach(i => i.DogHistory, dogHistoryList)); MongoDbClient.MongoManager<Dog>.Instance.UpdateOne( filter, Builders<Dog>.Update.Combine(updateList)); }
大叔对于这一点,也把它封装到了Lind.DDD.Repositories.Mongo的仓储里,完善了Update操作,修改了之前的递归处理逻辑,代码反而更简洁了,原理就是使用$set直接把原数据覆盖即可。
private void GenerateRecursion2( 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())) { var arr = propertyValue as IList; if (arr != null && arr.Count > 0) { fieldList.Add(Builders<TEntity>.Update.Set(property.Name, arr)); } } //实体 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); else GenerateRecursion(fieldList, sub, sub.GetValue(propertyValue), item, father + "." + property.Name); } } } //简单类型 else { if (property.Name != EntityKey)//更新集中不能有实体键_id { if (string.IsNullOrWhiteSpace(father)) fieldList.Add(Builders<TEntity>.Update.Set(property.Name, propertyValue)); else fieldList.Add(Builders<TEntity>.Update.Set(father + "." + property.Name, propertyValue)); } } }
对于产生的结果是我们可以接受的,可以对集合属性很方便的实现更新了。
产生的结果如下
欢迎大家继续关注mongodb技术!
继续关注大叔博客!
回到目录