zoukankan      html  css  js  c++  java
  • MongoDB学习笔记~大叔框架实体更新支持N层嵌套~递归递归我爱你!

    回到目录

    递归递归我爱你!只要你想做,就一定能成功!

    从一到二,从二到三,它是容易的,也是没什么可搞的,或者说,它是一种流水线的方式,而从三到十,从十到百,它注定要有一个质的突破,否则,它会把你累死,代码写的让你自己都觉得想吐!有时,我们是被逼出来的,对于一种功能的实现,我们有时需要有从三到十的态度中,就像0的出现是人类最大的突破之一……

    回归到实例,在MongoDB中实体可以嵌套,这在C#里叫做复杂属性,即类中也有类级的属性,这在面向对象里叫做“组合”(设计模式中的组合模式),它经常在日常开发环境中见到,大家都耳熟能详了,呵呵,而在mongodb里,如果希望对N层嵌套的类型进行update操作,这绝对不是一件容易的事,最起码在大叔框架里,在面向linq的语法里,它并不容易,但经过大叔的努力,和对递归的依赖,把这个问题解决了!

    这才有今天的文章:递归递归我爱你!

    一 从超级变态的类开始

     public class Person : Base
        {
    
            public Person()
            {
                Contact = new Test.Contact();
                OrderList = new List<Order>();
            }
    
    
            public string Name { get; set; }
            public DateTime LastContact { get; set; }
            public DateTime Birthday { get; set; }
            public int Age { get; set; }
    
            #region 值对象
            /// <summary>
            /// 统计
            /// </summary>
            public Total Total { get; set; }
            /// <summary>
            /// 联系方式和地址
            /// </summary>
            public Contact Contact { get; set; }
            #endregion
    
            #region 列表实体
            public List<Order> OrderList { get; set; }
            #endregion
        }
        public class Section
        {
            public string SectionID { get; set; }
            public string SectionName { get; set; }
        }
        public class Area
        {
            public Area()
            {
                Section = new Section();
            }
            public string Province { get; set; }
            public string City { get; set; }
            public string District { get; set; }
    
            public Section Section { get; set; }
        }
        public class Contact
        {
            public Contact()
            {
                Area = new Area();
            }
            public string PostCode { get; set; }
            public string Email { get; set; }
            public string Phone { get; set; }
    
            public Area Area { get; set; }
        }
        public class Total
        {
            public int Count { get; set; }
            public int Max { get; set; }
        }
        public class Order
        {
            public Order()
            {
                Id = MongoDB.Bson.ObjectId.GenerateNewId().ToString();
                this.OrderDetail = new List<OrderDetail>();
                this.User_Info = new User_Info();
            }
            public string UserId { get; set; }
            public string UserName { get; set; }
            public string Id { get; set; }
            public double Price { get; set; }
            public DateTime AddTime { get; set; }
    
            public User_Info User_Info { get; set; }
            public List<OrderDetail> OrderDetail { get; set; }
        }
    
        public class User_Info
        {
            public User_Info()
            {
                Id = MongoDB.Bson.ObjectId.GenerateNewId().ToString();
            }
            public string Id { get; set; }
            public string Name { get; set; }
        }
    
        public class OrderDetail
        {
            public OrderDetail()
            {
                Id = MongoDB.Bson.ObjectId.GenerateNewId().ToString();
            }
            public string Id { get; set; }
            public string OrderId { get; set; }
            public string ProductName { get; set; }
            public int Count { get; set; }
            public double Price { get; set; }
            public string SellerId { get; set; }
        }

    看到上面的类,绝对够你喝一壶的,呵呵,这是一个复杂的类型People,它有实体属性contact和列表属性OrderList

    而对于之前大叔的框架里,这种结构是不被支持的,大叔只能支持到3级嵌套,但这显然是不够的,最后大叔硬着头皮冲了上来,把这个骨头啃掉了,哈哈!

    下面贡献我的Recursion代码

            /// <summary>
            /// 递归构建Update操作串
            /// </summary>
            /// <param name="fieldList"></param>
            /// <param name="property"></param>
            /// <param name="propertyValue"></param>
            /// <param name="item"></param>
            /// <param name="father"></param>
            private void GenerateRecursion(
                  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);
                                            else
                                                GenerateRecursion(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);
                            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));
                    }
                }
            }
    
            /// <summary>
            /// 构建Mongo的更新表达式
            /// </summary>
            /// <param name="entity"></param>
            /// <returns></returns>
            private List<UpdateDefinition<TEntity>> GeneratorMongoUpdate(TEntity item)
            {
                var fieldList = new List<UpdateDefinition<TEntity>>();
                foreach (var property in typeof(TEntity).GetProperties(BindingFlags.Instance | BindingFlags.Public))
                {
                    GenerateRecursion(fieldList, property, property.GetValue(item), item, string.Empty);
                }
                return fieldList;
            }

    最后的结果,当然是在N层失败之后,取得了成功,呵呵!

    最后,送给大家一句,多看看数据结构和算法,对各位在程序开发领域,一定有非常大的帮助,最起码在看问题的角度上,会有更多的,更合理的选择!

    回到目录

  • 相关阅读:
    LeetCode-1-two-sum
    LeetCode-14-longest-common-prefix
    动态规划--矩阵链乘法
    动态规划--装配线调度算法
    LeetCode-9-palindrome-number
    LeetCode-8-string-to-integer-atoi
    LeetCode-7-Reverse Integer
    SElinux用户管理操作
    Minix3信号处理分析
    面对困难
  • 原文地址:https://www.cnblogs.com/lori/p/4553185.html
Copyright © 2011-2022 走看看