某些函数是否无法转换为等效表达式?

发布于 2024-12-24 18:24:10 字数 808 浏览 5 评论 0原文

这是我之前提出的问题的后续问题:

对传递表达式与 Func 参数感到困惑

接受的回答者建议将引用本地对象的表达式重构为 Linq to Entities 可以实际执行的内容后备存储(在我的例子中是 SQL Server)

我花了很长时间试图想出一些适合我正在做的事情的东西。我的原始

Func<Thing, bool> whereClause

引用是 Linq to Entities 或 SQL 在运行时无法理解的本地 Dictionary 对象。我尝试重构为多个列表,这些列表伪造了字典,然后是数组。每次,我都会收到运行时错误,抱怨上下文无法识别列表或数组索引器上的方法之类的东西。

最终我放弃了,只是提供了一个额外的方法,当我无法想出正确的表达式时,它需要一个 Func 参数。

我并不是想找到解决我的具体问题的方法,我只是想知道是否总是可以进行转换,例如转换

Func<Thing, bool>

为可以针对 Linq to Entities 运行的等效项

Expression<Func<Thing, bool>>

。 或者,如果有许多查询示例,您必须首先将数据拉入内存。

This is a follow up to a question I asked earlier seen here:

Confused about passing Expression vs. Func arguments

The accepted answerer there suggests refactoring an Expression referencing local objects into something that Linq to Entities can actually execute against the backing store (in my case SQL Server)

I've spent a long time trying to come up with something that will work for what I'm doing. My original

Func<Thing, bool> whereClause

was referencing a local Dictionary object which Linq to Entities or SQL could not understand at runtime. I tried refactoring into multiple lists which faked a dictionary, and Arrays after that. Each time, I got runtime errors complaining about the context doesn't recognize things like the methods on a List, or array indexers.

Eventually I gave up and just provided an additional method which takes a Func argument for when I cannot come up with the proper Expression.

I'm not trying to find a solution to my specific problem, I'm just wondering in general if it is always possible to convert, say a

Func<Thing, bool>

to an equivalent

Expression<Func<Thing, bool>>

which can run against Linq to Entities.
Or if there are many examples of querys where you simply must pull the data into memory first.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

撩人痒 2024-12-31 18:24:10

您不会将 Func 转换为表达式树 - 编译器会将 lambda 表达式 转换为表达式树...不,这并不总是可能的。例如,您无法将语句 lambda 转换为表达式树:

Expression<Func<string, int>> valid = text => text.Length;

Expression<Func<string, int>> invalid = text => { return text.Length; };

还有各种其他限制。

即使您可以创建表达式树(如果您手动执行此操作,则可以构建 C# 编译器无法构建的表达式树,特别是在 .NET 4 中),这与表示的表达式树不同LINQ to SQL(等)可以适当转换的东西。

You don't convert a Func to an expression tree - the compiler converts a lambda expression to an expression tree... and no, that's not always possible. For example, you can't convert a statement lambda to an expression tree:

Expression<Func<string, int>> valid = text => text.Length;

Expression<Func<string, int>> invalid = text => { return text.Length; };

There are various other restrictions, too.

Even when you can create an expression tree (and if you do it manually you can build ones which the C# compiler wouldn't, particularly in .NET 4) that's not the same thing as the expression tree representing something that LINQ to SQL (etc) can translate appropriately.

十二 2024-12-31 18:24:10

乔恩当然是正确的;将 lambda 转换为表达式树。

为了扩展一下他的“各种其他限制”手波:转换为表达式树的 lambda 可能不包含:

  • 主要对其状态突变有用的语句表达式:赋值、复合赋值、递增和递减运算
  • 任何类型的
  • 多维动态 操作数组初始值设定项
  • 删除了任何类型的部分方法
  • 基访问
  • 指针操作
  • sizeof(T),T 是内置类型除外
  • COM 样式索引属性调用
  • COM 样式“可选引用”调用
  • C 样式可变参数方法调用
  • 可选参数和命名参数调用
  • 方法组(当然,在调用中时除外)

这不是一个详尽的列表;还有一些其他奇怪的极端情况。但这应该涵盖其中的大多数。

Jon is of course correct; you turn a lambda into an expression tree.

To expand a bit on his "various other restrictions" handwave: a lambda converted to an expression tree may not contain:

  • statements
  • expressions useful primarily for their state mutations: assignment, compound assignment, increment and decrement operators
  • dynamic operations of any kind
  • multi-dimensional array initializers
  • removed partial methods
  • base access
  • pointer operations of any kind
  • sizeof(T) except for where T is a built-in type
  • COM-style indexed property invocations
  • COM-style "optional ref" invocations
  • C-style variadic method invocations
  • optional-argument and named-argument invocations
  • method groups (except of course when in an invocation)

That's not an exhaustive list; there are some other weird corner cases. But that should cover the majority of them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文