动态Lambda表达式:如何选择导航子属性生成GraphDTO
Fixing Nested Property Access in Expression Trees
Ah, I see the issue here! When dealing with nested properties (like VehicleMonitoringLog.dtUTCDateTime), you can't access them in a single step using Expression.PropertyOrField or GetProperty with the full dot-separated path. Those methods expect a direct member of the parent type, not a nested chain.
Here's how to correctly build the expression for your nested DateTime property:
Step-by-Step Explanation
- First, get the
VehicleMonitoringLogproperty from yourVehicleSensorLogtype. - Create an expression that accesses this property from your parameter (
xParam). - Then, get the
dtUTCDateTimeproperty from theVehicleMonitoringLogtype. - Build another expression that accesses this DateTime property from the result of the previous step.
Corrected Code
Let's update your code with this approach:
void Main() { // 由终端用户选择的键,用于按日期时间查看其值 var inputKey = nameof(VehicleSensorLog.iTemperatureSensor1); // 图表始终需要日期时间 var dateKey = nameof(VehicleSensorLog.VehicleMonitoringLog.dtUTCDateTime); Type gType = typeof(GraphDTO); Type inputType = typeof(VehicleSensorLog); ParameterExpression xParam = Expression.Parameter(inputType, "g"); // new语句 "new GraphDTO()" var xNew = Expression.New(gType); // 选择属性 var xPropValue = gType.GetProperty(nameof(GraphDTO.Value)); var xSourceValue = Expression.Property(xParam, inputType.GetProperty(inputKey)); var xPropDateTime = gType.GetProperty(nameof(GraphDTO.LogDateTime)); // Fix: Access nested property step by step // 1. Get VehicleMonitoringLog property from VehicleSensorLog var vehicleMonitoringLogProp = inputType.GetProperty(nameof(VehicleSensorLog.VehicleMonitoringLog)); // 2. Create expression to access VehicleMonitoringLog from xParam var vehicleMonitoringLogExpr = Expression.Property(xParam, vehicleMonitoringLogProp); // 3. Get dtUTCDateTime property from VehicleMonitoringLog type var dtUTCDateTimeProp = vehicleMonitoringLogProp.PropertyType.GetProperty(nameof(VehicleMonitoringLog.dtUTCDateTime)); // 4. Create expression to access dtUTCDateTime from VehicleMonitoringLog var xSourcePropDateTime = Expression.Property(vehicleMonitoringLogExpr, dtUTCDateTimeProp); // 绑定/映射原始属性到新GraphDTO属性(设置值 "Field1 = o.Field1") var xBindExpression = Expression.Bind(xPropValue, xSourceValue); // Fix: Use the correct DateTime expression here instead of xSourceValue var xBindExpressionDateTime = Expression.Bind(xPropDateTime, xSourcePropDateTime); // 初始化 "new Data { Field1 = o.Field1, Field2 = o.Field2 }" var xInit = Expression.MemberInit(xNew, new List<MemberAssignment>() { xBindExpression, xBindExpressionDateTime }); // 表达式 "o => new Data { Field1 = o.Field1, Field2 = o.Field2 }" var lambda = Expression.Lambda<Func<VehicleSensorLog, GraphDTO>>(xInit, xParam); // 最终根据创建的lambda选择日志 this.VehicleSensorLogs.Select(lambda).Take(10).Dump(); }
Key Fixes:
- Nested Property Access: We break down the nested property access into two separate
Expression.Propertycalls, each targeting a single level of the hierarchy. - Correct Binding: We fixed the
xBindExpressionDateTimeline to usexSourcePropDateTimeinstead of reusingxSourceValue(which was assigning the temperature value to the DateTime property—oops!).
This should correctly build the lambda expression that selects both the value property and the nested DateTime property into your GraphDTO.
内容的提问来源于stack exchange,提问作者Dawood Awan
相关产品推荐
相关产品推荐

