【MongoDB】递归获取字段更新表达式,更新复杂数据类型对象
生活随笔
收集整理的這篇文章主要介紹了
【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】递归获取字段更新表达式,更新复杂数据类型对象的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HDFS命令
- 下一篇: 互联网日志的种类、存储和计算