问题描述
我有一个Func<ProductItemVendor, bool>
存储在CompareProductItemVendorIds
中.我想在LINQ查询中使用该表达式.
I have a Func<ProductItemVendor, bool>
stored in CompareProductItemVendorIds
. I would like to use that expression in a LINQ query.
似乎是合法的:
var results =
Repository.Query<ProductItemVendor>().Where(CompareProductItemVendorIds);
但是,以下内容不合法:
However, the following is not legal:
var results = from v in Repository.Query<ProductItemVendor>()
where CompareProductItemVendorIds(v)
select v;
此代码会产生错误:
问题:
-
为什么这些陈述如此不同,以致我的
Func<>
在其中一项中是合法的,但在另一项中却不是合法的?我以为他们基本上都做同样的事情.
Why are these statements so different that my
Func<>
is legal in one but not the other? I thought they both basically did the same thing.
如何进行这项工作?我是否必须显式地将我的Func<>
创建为Expression<Func<>>
?
How can I make this work? Do I have to explicity create my Func<>
as an Expression<Func<>>
instead?
请在>使用Expression< Func<>中查看我的相关问题.在LINQ查询中.
推荐答案
Expression<Func<T,bool>>
和Func<T,bool>
之间存在很大差异.第一个是表达式树.您可以将其视为代码描述. Linq to Entities需要表达式树.因为它需要建立SQL查询.因此,需要代码描述才能将相同的动作转换为SQL.
There is big difference between Expression<Func<T,bool>>
and Func<T,bool>
. First one is an expression tree. You can think of it as description of code. Linq to Entities requires expression trees. Because it needs to build SQL query. So it needs description of code to translate same actions into SQL.
第二,Func<T,bool>
是具有指定签名的简单方法.这里没什么特别的.为什么在这里合法:
Second one, Func<T,bool>
is a simple method with specified signature. Nothing special here. Why its legal here:
Repository.Query<ProductItemVendor>().Where(CompareProductItemVendorIds);
很简单.有两种Where
扩展方法.前一个IQueryable<T>
,它需要表达式树(将被转换为SQL查询).另一个是IEnumerable<T>
的扩展,它希望使用序数方法进行内存中集合过滤(通常为C#代码).因此,您没有表达式树,因此选择了后一个.此处未生成SQL.这是你的情况.
It's simple. There are two Where
extension methods. One fore IQueryable<T>
, which expects expression tree (which will be translated into SQL query). And another is extension for IEnumerable<T>
which expects ordinal method for in-memory collection filtering (usual C# code). Thus you don't have expression tree, latter one is chosen. No SQL generated here. This is your case.
现在第二个查询:
from v in Repository.Query<ProductItemVendor>()
where CompareProductItemVendorIds(v)
select v
实际上这不是同一查询.等同于
Actually it's not same query. It's equivalent to
Repository.Query<ProductItemVendor>().Where(v => CompareProductItemVendorIds(v));
这里有lambda表达式,可以将其转换为表达式树.然后使用另一个Where
扩展名-一个用于IQueryable<T>
的扩展名.因此,Linq to Entities尝试将此表达式树转换为SQL.但是它应该转换什么呢?是的,调用某些内存方法.而且,当然,Linq to Entities无法做到这一点.
And here you have lambda expression, which can be converted into expression tree. And another Where
extension is used - one for IQueryable<T>
. So, Linq to Entities tries to convert this expression tree to SQL. But what it should convert? Yes, invocation of some in-memory method. And, of course, Linq to Entities fails to do that.
为了使查询正常工作,应使用Expression<Func<T,bool>>
.您可以手动构建它,也可以使用lambda表达式.
In order to make your query work, you should use Expression<Func<T,bool>>
. You can build it manually, or you can use lambda expression.
这篇关于使用Func<在LINQ查询中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!