【发布时间】:2021-06-15 16:08:15
【问题描述】:
Expressions 有问题。我有这个带有 Entity Framework Core LINQ Provider 的 lambda LINQ 查询:
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();
然后我有一个动态处理谓词的函数:
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;
}
消息是:
Unable to cast object of type 'System.Linq.Expressions.InstanceMethodCallExpression2' to type 'System.Linq.Expressions.LambdaExpression'.
谁能建议我做错了什么?
提前致谢,
朱利安
编辑: 作为对 Svyatoslav Danyliv 的回答。它给我的例外是:
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.
当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.
【问题讨论】:
-
你使用最新的 LINQKit 版本吗?
-
我没有!我已经更新到最新版本,但问题仍然存在:(
-
我的 github 问题已创建:github.com/scottksmith95/LINQKit/issues/140
-
马上检查。
标签: c# linq entity-framework-core linqkit