1. 程式人生 > >MongoDB學習筆記~Update方法更新集合屬性後的怪問題

MongoDB學習筆記~Update方法更新集合屬性後的怪問題

回到目錄

在對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.innerPropertyName
                                            fieldList.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的學生來說有所幫助!

回到目錄