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

这有效:

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

首先是因为它是一个扩展方法,并且正在将查询作为func执行,然后过滤列表, 请参见此处 。 所以一般来说它会自动转换到哪里

  Where(Func 

第二个不是因为它将你的where语句推送到数据库。 当评估lambda表达式时,它会像这样扩展:

 Where( Expresion>) 

这是一篇很好的文章 ,解释了Expressions vs Func

这是另一个有助于解释差异的SOpost

[编辑(BlueRaja)]

这个新的编辑似乎是正确的。 澄清一下:似乎Func可以隐式地转换为Expression> ,但不是相反。

两种类型的Where都有重载。 .Where(MyCustomMethod)调用Func一个,而.Where(o => MyCustomMethod(o))调用Expression>一个。

只是在这里形成一个“答案”,而不是评论..

我认为这是.NET 4中的一个新function,其中框架意识到此function无法转换为SQL,但可以在内存中轻松处理。 因此,它将整个数据集获取到本地计算机并继续查询处理。

事情是你的第一个片段,当翻译成表达式树时,会直接说它运行外部方法,而你的第二个片段不那么“直接”。 我想这就是为什么在第一种情况下,L2E可以很容易地理解发生了什么,并决定要做什么,而在第二种情况下,它“认为”最好发送一个exception并让开发人员更多地抓住他们的头脑^ _ ^