首页 > 解决方案 > 动态 Lambda 表达式 - 选择子属性

问题描述

我正在尝试生成一个 Lambda 表达式来选择一个日期属性和一个值属性来在客户端生成一个图表。

我想出了以下代码 - 可以很好地选择Value Property

void Main()
{
    // key to be selected by end user - to view values of it by datetime
    var inputKey = nameof(VehicleSensorLog.iTemperatureSensor1);
    
    // always need datetime for graph
    var dateKey = nameof(VehicleSensorLog.VehicleMonitoringLog.dtUTCDateTime);

    Type gType = typeof(GraphDTO);
    Type inputType = typeof(VehicleSensorLog);

    ParameterExpression xParam = Expression.Parameter(inputType, "g");

    // new statement "new GraphDTO()"
    var xNew = Expression.New(gType);

    // select properties
    var xPropValue = gType.GetProperty(nameof(GraphDTO.Value));
    var xSourceValue = Expression.Property(xParam, inputType.GetProperty(inputKey));
    var xPropDateTime = gType.GetProperty(nameof(GraphDTO.LogDateTime));

    // HOW TO DO THIS?
    // -----------------
    var xSourcePropDateTime = Expression.PropertyOrField(xParam, "VehicleMonitoringLog.dtUTCDateTime");

    // Bind / Map from Origional to New GraphDTO property (set value "Field1 = o.Field1")
    var xBindExpression = Expression.Bind(xPropValue, xSourceValue);
    var xBindExpressionDateTime = Expression.Bind(xPropDateTime, xSourceValue);

    // initialization "new Data { Field1 = o.Field1, Field2 = o.Field2 }"
    var xInit = Expression.MemberInit(xNew, new List<MemberAssignment>() { xBindExpression, xBindExpressionDateTime });

    // expression "o => new Data { Field1 = o.Field1, Field2 = o.Field2 }"
    var lambda = Expression.Lambda<Func<VehicleSensorLog, GraphDTO>>(xInit, xParam);

    // finally select the logs based on lambda created
    this.VehicleSensorLogs.Select(lambda).Take(10).Dump();

}

public class GraphDTO
{
    public DateTime LogDateTime { get; set; }
    public Double? Value { get; set; }
}

我无法从源中选择 DateTime 属性,因为它是导航(子)属性。我试过以下两种:

var xSourcePropDateTime = Expression.PropertyOrField(xParam, "VehicleMonitoringLog.dtUTCDateTime");



var xSourcePropDateTime = Expression.Property(xParam, inputType.GetProperty("VehicleMonitoringLog.dtUTCDateTime"));

如何为子属性创建表达式?

标签: c#linq

解决方案


PropertyOrField 方法不支持访问嵌套属性的点表示法,因此您需要像这样连续获取属性:

  var logItem = Expression.PropertyOrField(xParam, "VehicleMonitoringLog");
  var xSourcePropDateTime = Expression.PropertyOrField(logItem,"dtUTCDateTime");

推荐阅读