如何在Firebase Client的集合引用上应用任意查询运算符?
实现方案
推荐使用Func<Query, Query>委托作为查询参数,无需额外定义复杂结构,既能保留方法的泛型特性,又支持任意Firestore查询运算符的链式组合,无查询条件传入时默认查询全量集合,实现代码如下:
public async Task<IEnumerable<T>> GetCollectionAsync<T>(string path, Func<Query, Query> queryBuilder = null) { var collectionRef = _firestoreDb.Collection(path); // 有传入查询条件则应用,否则直接查询全量集合 Query query = queryBuilder != null ? queryBuilder(collectionRef) : collectionRef; var snapshot = await query.GetSnapshotAsync(); return snapshot.ConvertTo<T>(); }
调用示例
调用时可自由拼接任意Firestore支持的查询操作,支持多条件组合、排序、分页等需求:
// 单条件查询:查询所有年龄等于18的用户 var adultUsers = await GetCollectionAsync<User>("users", q => q.WhereEqualTo("Age", 18)); // 多条件组合查询:查询年龄≥18、所在城市为北京/上海、最多返回20条的用户数据 var targetUsers = await GetCollectionAsync<User>("users", q => q.WhereGreaterThanOrEqualTo("Age", 18) .WhereIn("City", new List<string>{"北京", "上海"}) .OrderBy("CreateTime") .Limit(20) );
如果要避免硬编码字段名,可以用nameof(实体类.字段名)代替字符串填写字段名,降低写错的概率。
可选封装方案(隐藏Firestore原生API)
如果你不希望上层调用方直接依赖Firestore的原生Query类型,可以自定义查询条件结构做一层封装,灵活性略低于委托方案:
// 定义支持的查询运算符枚举 public enum FirestoreQueryOperator { EqualTo, In, GreaterThanOrEqualTo, LessThan, // 按需补充其他运算符 } // 定义查询条件类 public class FirestoreQueryCondition { public string FieldName { get; set; } public FirestoreQueryOperator Operator { get; set; } public object Value { get; set; } } // 修改后的查询方法 public async Task<IEnumerable<T>> GetCollectionAsync<T>(string path, List<FirestoreQueryCondition> conditions = null) { var collectionRef = _firestoreDb.Collection(path); Query query = collectionRef; if (conditions != null && conditions.Any()) { foreach (var condition in conditions) { query = condition.Operator switch { FirestoreQueryOperator.EqualTo => query.WhereEqualTo(condition.FieldName, condition.Value), FirestoreQueryOperator.In => query.WhereIn(condition.FieldName, (System.Collections.IEnumerable)condition.Value), FirestoreQueryOperator.GreaterThanOrEqualTo => query.WhereGreaterThanOrEqualTo(condition.FieldName, condition.Value), FirestoreQueryOperator.LessThan => query.WhereLessThan(condition.FieldName, condition.Value), _ => query }; } } var snapshot = await query.GetSnapshotAsync(); return snapshot.ConvertTo<T>(); }
内容的提问来源于stack exchange,提问作者Oignon_Rouge
相关产品推荐
相关产品推荐

