当前位置:Gxlcms > 数据库问题 > MongoDB学习笔记~大叔框架实体更新支持N层嵌套~递归递归我爱你!

MongoDB学习笔记~大叔框架实体更新支持N层嵌套~递归递归我爱你!

时间:2021-07-01 10:21:17 帮助过:2人阅读

一 从超级变态的类开始

 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层失败之后,取得了成功,呵呵!

 

技术分享

人气教程排行