【问题标题】:Are some Funcs impossible to convert to equivalent Expressions?某些 Funcs 是否无法转换为等效的表达式?
【发布时间】:2012-01-04 19:38:34
【问题描述】:

这是我之前在这里看到的一个问题的后续:

Confused about passing Expression vs. Func arguments

那里接受的回答者建议将引用本地对象的表达式重构为 Linq to Entities 可以对后备存储实际执行的东西(在我的情况下是 SQL Server)

我花了很长时间试图想出一些对我正在做的事情有用的东西。我的原创

Func<Thing, bool> whereClause

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

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

我并不是想为我的具体问题找到解决方案,我只是想知道一般来说是否总是可以转换,比如说

Func<Thing, bool>

等价的

Expression<Func<Thing, bool>>

可以针对 Linq to Entities 运行。 或者,如果有很多查询示例,您只需必须先将数据拉入内存。

【问题讨论】:

    标签: c# linq sql-server-2008 c#-4.0 linq-to-entities


    【解决方案1】:

    您不会将 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(等)可以适当转换的内容的表达式树。

    【讨论】:

      【解决方案2】:

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

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

      • 声明
      • 主要用于状态突变的表达式:赋值、复合赋值、递增和递减运算符
      • 任何类型的动态操作
      • 多维数组初始化器
      • 删除了部分方法
      • 基本访问
      • 任何类型的指针操作
      • sizeof(T) 除了 T 是内置类型
      • COM 样式的索引属性调用
      • COM 样式的“可选引用”调用
      • C 风格的可变参数方法调用
      • 可选参数和命名参数调用
      • 方法组(当然调用时除外)

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

      【讨论】:

      • 谢谢埃里克。这些只是对语言本身提供的限制,对吗?这意味着您可以满足所有这些条件,但仍然有 Linq to SQL 无法翻译它?
      • @Erix:正确。我不知道 LINQ to SQL 的限制是什么。
      猜你喜欢
      • 2012-11-30
      • 2011-08-04
      • 2017-07-21
      • 2012-08-21
      • 1970-01-01
      • 2012-02-17
      • 1970-01-01
      • 2014-08-05
      • 1970-01-01
      相关资源
      最近更新 更多