LINQ to Entities无法识别方法'Int64 Max(Int64,Int64)'方法,并且此方法无法转换为存储表达式

时间:2013-08-08 11:31:42

标签: c# linq-to-entities runtime-error

我在运行时

中收到此错误消息
  

LINQ to Entities无法识别方法'Int64 Max(Int64,Int64)'方法,并且此方法无法转换为商店表达式。

当我尝试这样做时:

return _dbContext.Appointment.Where(x => Math.Max(x.Appointment.StartTime.Ticks, startTime.Ticks) <= Math.Min(x.Appointment.EndTime.Ticks, endTime.Ticks));

这个查询背后的想法是“如果最新的开始时间是在最早的结束时间之前,那么你在日期和时间中会有一些重叠/触摸”。

有没有办法让这条线路正常工作?我已经检查EntityFunctions是否有'某事',但事实并非如此。

2 个答案:

答案 0 :(得分:4)

MaxMin可以像这样实现:

public static long Max(long a, long b)
{
    return a < b ? b : a;
}
public static long Min(long a, long b)
{
    return a < b ? a : b;
}

自LINQ to Entities understands ? :以来,您可以将这些内容嵌入到您的表达式中。另外,由于不支持Ticks,但DateTime比较是......

Math.Max(x.Appointment.StartTime.Ticks, startTime.Ticks)

变为

(x.Appointment.StartTime < startTime ? startTime : x.Appointment.StartTime)

答案 1 :(得分:2)

您必须始终牢记每个IQueryable提供程序都以自己的方式实现。该查询将在Linq to Objects中起作用(因为它不会被转换为任何内容),但在IQueryable提供程序中可能有效,也可能无效。

在您的具体情况下,它告诉您它不知道如何将Math.Max和Math.Min转换为SQL命令。这是完全正确的,因为EF不承认这些方法。

在我看来,完成所需内容的最简单方法是使用两个不同的查询读取最大值和最小值,然后在普通c#中执行逻辑。像这样:

var min = mycontext.MyDbSet.Min(c => c.Field);
var max = mycontext.MyDbSet.Max(c => c.Field);
if (max <= min)
{
    // do something
}