这有效:
Entities.WorkOrderSet.Where(MyCustomMethod);
这不是:
Entities.WorkOrderSet.Where(o => MyCustomMethod(o));
( [编辑] 即使没有new
,也无效)
我理解为什么第二个不起作用 - 但是为什么世界上第一个工作呢?我不应该得到一个“LINQ-to-Entities无法识别方法......“在运行时,与第二个一样?
供参考,这是MyCustomMethod
public bool MyCustomMethod(WorkOrder workOrder)
{
return !workOrder.WorkOrderNum.StartsWith("A", StringComparison.CurrentCultureIgnoreCase);
}
使用EF1,而不是EF4
答案 0 :(得分:6)
首先是因为它是一个扩展方法,并且正在将查询作为func执行,然后过滤列表see here。
所以一般来说它会自动转换到
Where(Func<WorkOrder, bool>
第二个不是因为它将你的where语句推送到db。当评估lambda表达式时,它会像这样展开:
Where( Expresion<Func<WorkOrder, bool>>)
这是一个很好的article解释Expressions与Func
Here is another SO post that helps to explain the difference
[编辑(BlueRaja)]
这个新编辑似乎是正确的。澄清一下:似乎Func<WorkOrder, bool>
可隐式转换为Expression<Func<WorkOrder, bool>>
,但不是相反。
两种类型都有Where
的重载。 .Where(MyCustomMethod)
正在调用Func<WorkOrder, bool>
,而.Where(o => MyCustomMethod(o))
正在调用Expression<Func<WorkOrder, bool>>
。
答案 1 :(得分:1)
在此处将此形成为“答案”,而不是评论..
我认为这是.NET 4中的一项新功能,其中框架意识到此功能无法转换为SQL,但可以在内存中轻松处理。因此,它将整个数据集获取到本地计算机并继续查询处理..
这是你的第一个片段,当翻译成表达式树时,会直接说它运行外部方法,而你的第二个片段不那么“直接”。我想这就是为什么在第一种情况下,L2E可以很容易地理解发生了什么,并决定要做什么,而在第二种情况下,它“认为”最好发送一个异常并让开发人员更多地抓住他们的头脑^ _ ^