如何创建支持列名访问的数组Expression?
解决MongoDB BsonDocument动态表达式筛选问题
要实现你想要的x['columnName'].ToString() == value这种基于列名的筛选表达式,关键是在表达式树里正确调用BsonDocument的字符串索引器,再链式调用ToString()方法,最后和目标值做相等比较。下面是修改后的代码及关键逻辑说明:
核心修改思路
- 替换原来的恒真表达式,改为通过列名访问BsonDocument字段
- 对获取到的字段值调用
ToString()方法 - 将字段字符串值与目标值做相等比较,多条件用逻辑与拼接
修改后的完整代码
private static Expression<Func<BsonDocument, bool>> BuildPredicate(JArray valueNames, string row, string[] colNames) { Expression predicate = null; ParameterExpression argParam = Expression.Parameter(typeof(BsonDocument), "s"); List<Tuple<string, string>> parameters = valueNames .Select(vn => Tuple.Create(vn[TARGET].ToString(), row.Split(',')[GetFieldIndex(new Field { name = vn[TARGET].ToString() }, colNames)])) .ToList(); foreach (var parameter in parameters) { // 1. 生成 s["columnName"] 的表达式:调用BsonDocument的字符串索引器 var columnNameExpr = Expression.Constant(parameter.Item1); var fieldAccessExpr = Expression.Property(argParam, "Item", columnNameExpr); // 2. 对字段值调用 ToString() 方法 var toStringMethod = typeof(BsonValue).GetMethod("ToString", Type.EmptyTypes); var toStringExpr = Expression.Call(fieldAccessExpr, toStringMethod); // 3. 生成 字段字符串值 == 目标值 的相等表达式 var targetValueExpr = Expression.Constant(parameter.Item2); var equalExpr = Expression.Equal(toStringExpr, targetValueExpr); // 4. 多条件用逻辑与拼接 predicate = predicate == null ? equalExpr : Expression.AndAlso(predicate, equalExpr); } return Expression.Lambda<Func<BsonDocument, bool>>(predicate, argParam); }
代码细节说明
- 字段访问:BsonDocument的字符串索引器对应属性
Item,通过Expression.Property传入列名常量,就能生成s["columnName"]的访问表达式,解决了ArrayAccess只能用索引的问题。 - ToString调用:获取
BsonValue的无参ToString()方法,用Expression.Call生成方法调用表达式,实现字段值转字符串的逻辑。 - 条件组合:每个列的筛选条件通过
AndAlso拼接,最终生成多条件同时满足的Lambda表达式。
内容的提问来源于stack exchange,提问作者AnxiousdeV
相关产品推荐
相关产品推荐

