CosmosDB通用OrderBy查询与倒序取数:基于Azure项目修改GetItemsAsync方法
CosmosDB通用OrderBy查询与最新数据优先获取实现
嘿,我来帮你基于现有的GetItemsAsync方法扩展出支持排序、尤其是优先获取最新数据的功能!咱们一步步来:
1. 先回顾你现有的基础方法
首先把你提供的代码补全完整,方便后续扩展:
public static async Task<List<T>> GetItemsAsync(Expression<Func<T, bool>> predicate, int maxItemCount = -1) { IDocumentQuery<T> query = client.CreateDocumentQuery<T>( UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId), new FeedOptions { MaxItemCount = maxItemCount }) .Where(predicate) .AsDocumentQuery(); List<T> results = new List<T>(); while (query.HasMoreResults) { results.AddRange(await query.ExecuteNextAsync<T>()); } return results; }
2. 扩展支持通用OrderBy的重载方法
咱们新增一个重载版本,允许传入排序表达式和排序方向,这样就能灵活实现各种排序需求,包括优先获取最新数据(按时间字段降序):
public static async Task<List<T>> GetItemsAsync( Expression<Func<T, bool>> predicate, Expression<Func<T, object>> orderByExpression, bool isDescending = false, int maxItemCount = -1) { IOrderedQueryable<T> orderedQuery; // 先构建基础查询 var baseQuery = client.CreateDocumentQuery<T>( UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId), new FeedOptions { MaxItemCount = maxItemCount }) .Where(predicate); // 应用排序逻辑 if (isDescending) { orderedQuery = baseQuery.OrderByDescending(orderByExpression); } else { orderedQuery = baseQuery.OrderBy(orderByExpression); } // 执行查询并返回结果 IDocumentQuery<T> query = orderedQuery.AsDocumentQuery(); List<T> results = new List<T>(); while (query.HasMoreResults) { results.AddRange(await query.ExecuteNextAsync<T>()); } return results; }
3. 封装“优先获取最新数据”的便捷方法
如果你的实体类普遍有类似CreateTime(创建时间)或者UpdateTime(更新时间)的字段,咱们可以再封装一个更易用的方法,直接实现按时间降序获取最新数据:
/// <summary> /// 按指定条件获取最新数据(默认按CreateTime降序) /// </summary> public static async Task<List<T>> GetLatestItemsAsync( Expression<Func<T, bool>> predicate, Expression<Func<T, DateTime>> timeFieldExpression = null, int maxItemCount = -1) { // 默认使用CreateTime作为排序字段,你可以根据实际情况修改 var orderByExpr = timeFieldExpression ?? (x => (DateTime)typeof(T).GetProperty("CreateTime").GetValue(x)); return await GetItemsAsync(predicate, orderByExpr, isDescending: true, maxItemCount: maxItemCount); }
注意:如果你的实体类都统一实现了带时间字段的接口(比如
ITimestampedEntity),可以把上面的反射逻辑换成强类型调用,避免反射带来的性能损耗,比如:public interface ITimestampedEntity { DateTime CreateTime { get; } } // 然后方法约束为where T : ITimestampedEntity public static async Task<List<T>> GetLatestItemsAsync<T>(Expression<Func<T, bool>> predicate, int maxItemCount = -1) where T : ITimestampedEntity { return await GetItemsAsync(predicate, x => x.CreateTime, isDescending: true, maxItemCount: maxItemCount); }
4. 使用示例
示例1:通用OrderBy查询(按名称升序)
var products = await GetItemsAsync<Product>(p => p.Price > 100, p => p.Name, isDescending: false);
示例2:优先获取最新创建的用户数据
// 使用便捷方法 var latestUsers = await GetLatestItemsAsync<User>(u => u.IsActive); // 或者直接调用重载方法 var latestUsers = await GetItemsAsync<User>(u => u.IsActive, u => u.CreateTime, isDescending: true);
这样改造后,你的方法既保留了原有的灵活性,又能轻松实现排序和最新数据优先的需求啦!
内容的提问来源于stack exchange,提问作者erincerol
相关产品推荐
相关产品推荐

