使用Dapper时如何通过变量访问动态对象的属性值
使用Dapper时如何通过变量访问动态对象的属性值
我太懂你这个痛点了——用Dapper查出来的动态对象,想通过变量当属性名取值的时候,常规的.语法根本不管用,硬编码属性名又完全不符合你“数据库驱动、动态属性”的需求。下面给你两个最实用的解决办法,都是开发者们常用的:
方法1:转成字典接口直接取值(推荐)
其实Dapper返回的动态对象(也就是DapperRow)本身就实现了IDictionary<string, object>接口,这意味着你可以直接把它转成字典,然后用你的propertyName变量当键来取值,不仅代码简单,性能还比反射好一大截:
var records = await con.QueryAsync(queryBuilderResult.Query, queryBuilderResult.SqlParams); List<object> rowValues = []; foreach (var row in records) { if (row == null) continue; // 把动态对象转成字典接口 var rowDictionary = row as IDictionary<string, object>; if (rowDictionary != null) { // 用TryGetValue避免属性不存在时抛出异常 if (rowDictionary.TryGetValue(propertyName, out var propertyValue)) { rowValues.Add(propertyValue); } // 如果你能100%确定属性一定存在,也可以直接写 // rowValues.Add(rowDictionary[propertyName]); } } filter[dependsOnField] = rowValues;
方法2:用反射实现你的GetPropertyValue方法
如果因为某些特殊场景不能用字典接口,那可以补全你代码里的GetPropertyValue方法,用反射来动态取值:
private object GetPropertyValue(object targetObj, string propertyName) { if (targetObj == null) return null; // 先尝试获取属性(大部分Dapper场景用这个) var propertyInfo = targetObj.GetType().GetProperty(propertyName); if (propertyInfo != null) { return propertyInfo.GetValue(targetObj); } // 少数情况下动态对象用字段存储,再尝试字段 var fieldInfo = targetObj.GetType().GetField(propertyName); return fieldInfo?.GetValue(targetObj); }
不过要提醒一句:反射的性能比字典接口差很多,如果是循环处理大量数据的话,优先选方法1。
额外小建议
如果你的查询结果结构其实是相对固定的,不如直接定义一个实体类,让Dapper直接映射到强类型对象,这样后续取值不仅更安全,还能避免动态对象的各种小麻烦:
// 先定义和查询结果匹配的实体类 public class DataRecord { public string TargetProperty { get; set; } // 其他和查询字段对应的属性... } // 查询时直接指定实体类型 var records = await con.QueryAsync<DataRecord>(queryBuilderResult.Query, queryBuilderResult.SqlParams);
内容来源于stack exchange
相关产品推荐
相关产品推荐

