Dawood Awan
Dawood Awan

Reputation: 7348

Dynamic Lambda Expression - Select a sub property

I'm try to generate a Lambda Expression to Select a Date Property and a Value Property to generate a Graph on client side.

I've come up with the following code - Which works fine to select the 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; }
}

I'm having trouble selecting the DateTime property from the source because it is a navigation (sub) property. I've tried the following two:

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



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

How do I create the Expression for a sub property?

Upvotes: 0

Views: 377

Answers (1)

Nikita K
Nikita K

Reputation: 406

The PropertyOrField method does not support the dot notation for accessing nested properties, so you need to get properties consecutive like this:

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

Upvotes: 1

Related Questions