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); }
结果就是我们想好的,怎么样,用法挺友好吧