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的学生来说有所帮助!

回到目录

 

posted @   张占岭  阅读(5682)  评论(3编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 记一次.NET内存居高不下排查解决与启示
历史上的今天:
2012-05-29 架构,改善程序复用性的设计~第三讲 实现一种功能的代码只能出现在一处(续)
点击右上角即可分享
微信分享提示