繁体   English   中英

在 LINQ 查询中使用 Func<>

[英]Using Func<> in LINQ Query

我有一个Func<ProductItemVendor, bool>存储在CompareProductItemVendorIds 我想在 LINQ 查询中使用该表达式。

看起来以下是合法的:

var results =
    Repository.Query<ProductItemVendor>().Where(CompareProductItemVendorIds);

但是,以下情况是不合法的:

var results = from v in Repository.Query<ProductItemVendor>()
              where CompareProductItemVendorIds(v)
              select v;

此代码产生错误:

LINQ to Entities 不支持 LINQ 表达式节点类型“Invoke”。

问题:

  1. 为什么这些语句如此不同,以至于我的Func<>在其中一个是合法的,而在另一个中不合法? 我认为他们基本上都做了同样的事情。

  2. 我怎样才能使这项工作? 我是否必须明确创建我的Func<>作为Expression<Func<>>代替?

请参阅我在Using Expression<Func<>> in a LINQ Query 中的相关问题。

Expression<Func<T,bool>>Func<T,bool>之间有很大的区别。 第一个是表达式树。 您可以将其视为代码的描述。 Linq to Entities 需要表达式树。 因为它需要构建 SQL 查询。 所以它需要代码描述来将相同的操作转换为 SQL。

第二个, Func<T,bool>是一个带有指定签名的简单方法。 这里没什么特别的。 为什么它在这里合法:

Repository.Query<ProductItemVendor>().Where(CompareProductItemVendorIds);

这很简单。 有两种Where扩展方法。 一个前IQueryable<T> ,它期望表达式树(将被转换为 SQL 查询)。 另一个是IEnumerable<T>扩展,它需要用于内存中集合过滤的序数方法(通常是 C# 代码)。 因此你没有表达式树,选择后一个。 这里没有生成 SQL。 这是你的情况。

现在第二个查询:

from v in Repository.Query<ProductItemVendor>()
where CompareProductItemVendorIds(v)
select v

实际上这不是相同的查询。 它相当于

Repository.Query<ProductItemVendor>().Where(v => CompareProductItemVendorIds(v));

在这里你有 lambda 表达式,它可以转换成表达式树。 另一个Where扩展被使用 - 一个用于IQueryable<T> 因此,Linq to Entities 尝试将此表达式树转换为 SQL。 但它应该转换什么? 是的,调用一些内存中的方法。 当然,Linq to Entities 没有做到这一点。

为了使您的查询工作,您应该使用Expression<Func<T,bool>> 您可以手动构建它,也可以使用 lambda 表达式。

你的第一个版本有效的原因是 Linq 太聪明了,不利于它自己。 相当于你的第一个版本实际上是

IEnumerable<ProductItemVendor> temp = Repository.Query<ProductItemVendor>().AsEnumerable();
var results = temp.Where(CompareProductItemVendorIds);

所以,当你执行你查询你在你的数据库返回的每一行,然后执行Where在本地计算机上的内存。

要在数据库上执行 Where 子句,您必须将CompareProductItemVendorIds的类型更改为Expression<Func<ProductItemVendor, bool>>

无法从Func<TIn, TOut> “转换”到Expression<Func<TIn. Tout>> Expression<Func<TIn. Tout>> ,您必须将代码重写为最初是一个表达式,然后您可以通过调用CompareProductItemVendorIds.Compile()转换为Func<TIn, TOut>

Expression<Func<ProductItemVendor, bool>> CompareProductItemVendorIds = //...
Func<ProductItemVendor, bool> CompareProductItemVendorIdsAsFunc = CompareProductItemVendorIds.Compile();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM