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);
        }
复制代码

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

 

回到目录

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