为什么LINQ-to-Entities会识别我的自定义方法?

时间:2010-04-20 13:42:55

标签: c# entity-framework linq-to-entities

这有效:

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

2 个答案:

答案 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可以很容易地理解发生了什么,并决定要做什么,而在第二种情况下,它“认为”最好发送一个异常并让开发人员更多地抓住他们的头脑^ _ ^