Reputation: 7348
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
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