I have a problem with Expressions
. I have this lambda LINQ query with Entity Framework Core LINQ Provider:
IQueryable<ProcessValueBase> valuesSubquery;
switch (req.Period)
{
case TimePeriodType.Current:
valuesSubquery = dbContext.ProcessValues;
break;
case TimePeriodType.Day:
case TimePeriodType.Week:
case TimePeriodType.Month:
valuesSubquery = dbContext.NormalizedLogValues;
break;
default:
valuesSubquery = dbContext.ProcessValues;
break;
}
var res = dbContext.Rooms.Select(r => new
{
RoomId = r.Id,
ZoneId = r.ZoneId,
IdealSetpoint = r.Group.Setpoints.First(sp => sp.ClimaticZoneId == dbContext.ClimaticZonesLogs.OrderByDescending(cz => cz.Timestamp).First().ClimaticZoneId).Setpoint,
Devices = r.Devices
.Select(rd => rd.Device)
.Select(d => new
{
Id = d.Id,
Name = d.Name,
//Setpoint = GetQuery(rd.Device.Id).Average(t=>t.Value)
Setpoint = valuesSubquery.Where(GetQuery(req.Period, d)).Average(t => t.Value)
})
}
).ToList();
Then I have a function that deals with the predicate dynamically:
private Expression<Func<ProcessValueBase,bool>> GetQuery(string period, DeviceModel device)
{
var predicate = PredicateBuilder.New<ProcessValueBase>();
predicate = predicate.And(v => v.TagSettings.DeviceId == device.Id);
predicate = predicate.And(v => v.TagSettings.TagTypeId == GetSetpointTagTypeId(device.DeviceTypeId));
predicate = predicate.And(v => v.ClimaticZoneId == dbContext.ClimaticZonesLogs.OrderByDescending(cz => cz.Timestamp).First().ClimaticZoneId);
var utcTime = DateTime.Now.ToUniversalTime();
switch (period)
{
case TimePeriodType.Day:
var startOfDay = utcTime.StartOfDay();
predicate = predicate.And(v => v.Timestamp >= startOfDay && v.Timestamp < startOfDay.AddDays(1));
break;
case TimePeriodType.Week:
var startOfWeek = utcTime.FirstDayOfWeek();
predicate = predicate.And(v => v.Timestamp >= startOfWeek && v.Timestamp < startOfWeek.AddDays(7));
break;
case TimePeriodType.Month:
var startOfMonth = utcTime.FirstDayOfMonth();
predicate = predicate.And(v => v.Timestamp >= startOfMonth && v.Timestamp < startOfMonth.AddMonths(1));
break;
default:
break;
}
return predicate;
}
The error that I'm getting is as follows:
The message is:
Unable to cast object of type 'System.Linq.Expressions.InstanceMethodCallExpression2' to type 'System.Linq.Expressions.LambdaExpression'.
Can anyone suggest what am I doing wrong?
Thanks in advance,
Julian
EDIT: As an answer to Svyatoslav Danyliv answer. The exception that it gives me is:
The LINQ expression 'DbSet<NormalizedLogValueModel>()
.Where(n => (v, device) => v.TagSettings.DeviceId == device.Id && v.TagSettings.TagTypeId == SetpointSideViewHandler.GetSetpointTagTypeId(device.DeviceTypeId) && v.ClimaticZoneId == DbSet<ClimaticZoneLogModel>()
.OrderByDescending(c0 => c0.Timestamp)
.Select(c0 => c0.ClimaticZoneId)
.First() && v.Timestamp >= __startOfDay_0 && v.Timestamp < __AddDays_1
.Invoke(
arg1: n,
arg2: EntityShaperExpression:
EntityType: DeviceModel
ValueBufferExpression:
ProjectionBindingExpression: Inner
IsNullable: True
))' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
When GetQuery(req.Period).Compile()(p,d)
:
The LINQ expression 'DbSet<NormalizedLogValueModel>()
.Where(n => Invoke(__Compile_0, n, [RelationalEntityShaperExpression])
)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.