MongoDB学习笔记~以匿名对象做为查询参数,方便查询子对象

回到目录

对于MongoDB的封装还在继续,对于不断追求简单的编程还在继续,对于喜欢代码的那么感觉,还在继续...

当你的mongo数据表里有子对象时,尤其是列表对象时,使用官方的驱动很是不爽,要记得很多新的对象类型,麻烦,所以,将它进行封装,让GetModel支持匿名参数!

表结构可能是这样

希望查询的语句变成这样

看了上面的语句感觉挺酷吧,呵呵,下面看一下实现的代码,今天下午写的,呵呵!

  public IEnumerable<TEntity> GetModel<U>(U template)

        {

            return _table.Find(GeneratorMongoQuery(template)).ToListAsync().Result;

        }



        public PagedResult<TEntity> GetModel<U>(int pageIndex, int pageSize)

        {

            return this.GetModel(new { }, pageIndex, pageSize);



        }



        public PagedResult<TEntity> GetModel<U>(U template, int pageIndex, int pageSize)

        {

            return this.GetModel(template, new { }, pageIndex, pageSize);

        }



        public PagedResult<TEntity> GetModel<U, O>(U template, O orderby, int pageIndex, int pageSize)

        {

            #region 条件过滤

            BsonDocumentFilterDefinition<TEntity> filterDefinition = GeneratorMongoQuery(template);

            #endregion



            #region 排序处理

            SortDefinition<TEntity> sorts = new ObjectSortDefinition<TEntity>(new { });

            foreach (var item in typeof(O).GetProperties())

            {

                if ((OrderType)item.GetValue(orderby) == OrderType.Asc)

                    sorts = sorts.Ascending(item.Name);

                else

                    sorts = sorts.Descending(item.Name);

            }

            #endregion



            #region 分页处理

            var skip = (pageIndex - 1) * pageSize;



            var recordCount = _table.Find(filterDefinition).CountAsync(new CancellationToken()).Result;

            var limit = pageSize;

            return new PagedResult<TEntity>(

                recordCount,

                (int)(recordCount + pageSize - 1) / pageSize,

                pageSize,

                pageIndex,

                _table.Find(filterDefinition)

                      .Sort(sorts)

                      .Skip(skip)

                      .Limit(limit)

                      .ToListAsync().Result);

            #endregion





        }

提出了一个条件过滤的私有方法,因为它的逻辑在两个方法里都用了,所以进行提取

   /// <summary>

        /// 构建Mongo的查询表达式,通过一个匿名对象

        /// </summary>

        /// <typeparam name="U"></typeparam>

        /// <param name="template"></param>

        /// <returns></returns>

        private BsonDocumentFilterDefinition<TEntity> GeneratorMongoQuery<U>(U template)

        {

            var qType = typeof(U);

            var outter = new BsonDocument();

            var simpleQuery = new BsonDocument();

            foreach (var item in qType.GetProperties())

            {

                if (item.PropertyType.IsClass && item.PropertyType != typeof(string))

                {

                    //复杂类型,导航属性,类对象和集合对象 

                    foreach (var sub in item.PropertyType.GetProperties())

                    {

                        simpleQuery.Add(new BsonElement(item.Name + "." + sub.Name,

                           BsonValue.Create(sub.GetValue(item.GetValue(template)))

                            ));

                    }

                }

                else

                {

                    //简单类型,ValueType和string

                    simpleQuery.Add(new BsonElement(item.Name,

                      BsonValue.Create(item.GetValue(template))

                        ));

                }

            }

            return new BsonDocumentFilterDefinition<TEntity>(simpleQuery);

        }

结果就是我们想好的,怎么样,用法挺友好吧

 

回到目录

你可能感兴趣的:(mongodb)