组合两个 Linq lambda 表达式

2024-02-05

Expression<Func<MyObject, string>> fn1 = x => x.PossibleSubPath.MyStringProperty;

Expression<Func<string, bool>> fn2 = x => x.Contains("some literal");

有没有办法创建一个新的 lambda 表达式,它基本上使用 fn1 的输出并将其用作 fn2 的输入?

Expression<Func<MyObject, bool>> fnCombined = ...

我知道我可以立即创建该函数,但问题是我正在编写一些通用代码,因此确实需要能够分别创建这两个函数,然后以 Linq 可以使用它们的方式组合它们我的数据库对象(实体框架)。


因此,从逻辑上讲,我们希望能够创建一个新的 lambda,其中它具有第一个函数的输入参数,以及使用该参数调用第一个函数的主体,然后将结果作为参数传递给第二个函数,然后返回该函数。

我们可以使用以下方法轻松复制这一点Expression对象:

public static Expression<Func<T1, T3>> Combine<T1, T2, T3>(
    Expression<Func<T1, T2>> first,
    Expression<Func<T2, T3>> second)
{
    var param = Expression.Parameter(typeof(T1), "param");
    var body = Expression.Invoke(second, Expression.Invoke(first, param));
    return Expression.Lambda<Func<T1, T3>>(body, param);
}

遗憾的是,EF 和大多数其他查询提供程序并不真正知道如何处理它,并且无法正常运行。每当他们击中Invoke表达他们通常只是抛出某种异常。一些can不过处理一下。理论上,如果他们编写的信息具有足够的鲁棒性来获取信息,那么他们需要的所有信息都在那里。

然而,从概念的角度来看,我们可以做的是,用我们正在创建的新 lambda 的参数替换该 lambda 主体中第一个 lambda 参数的每个实例,然后替换第二个 lambda 中第二个 lambda 参数的所有实例与第一个 lambda 的新主体。从技术上讲,如果这些表达式有副作用,并且这些参数多次使用,它们就不会相同,但由于这些表达式将由 EF 查询提供程序解析,因此它们实际上不应该有副作用。

感谢 David B 提供链接这个相关问题 https://stackoverflow.com/a/9683506/8155它提供了一个ReplaceVisitor执行。我们可以用它ReplaceVisitor遍历表达式的整个树并将一个表达式替换为另一个表达式。该类型的实现是:

class ReplaceVisitor : ExpressionVisitor
{
    private readonly Expression from, to;
    public ReplaceVisitor(Expression from, Expression to)
    {
        this.from = from;
        this.to = to;
    }
    public override Expression Visit(Expression node)
    {
        return node == from ? to : base.Visit(node);
    }
}

现在我们可以写我们的proper Combine method:

public static Expression<Func<T1, T3>> Combine<T1, T2, T3>(
    this Expression<Func<T1, T2>> first,
    Expression<Func<T2, T3>> second)
{
    var param = Expression.Parameter(typeof(T1), "param");

    var newFirst = new ReplaceVisitor(first.Parameters.First(), param)
        .Visit(first.Body);
    var newSecond = new ReplaceVisitor(second.Parameters.First(), newFirst)
        .Visit(second.Body);

    return Expression.Lambda<Func<T1, T3>>(newSecond, param);
}

和一个简单的测试用例,只是为了演示发生了什么:

Expression<Func<MyObject, string>> fn1 = x => x.PossibleSubPath.MyStringProperty;
Expression<Func<string, bool>> fn2 = x => x.Contains("some literal");

var composite = fn1.Combine(fn2);

Console.WriteLine(composite);

将打印出:

param => param.PossibleSubPath.MyStringProperty.Contains("一些文字")

这正是我们想要的;查询提供者将知道如何解析类似的内容。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

组合两个 Linq lambda 表达式 的相关文章

  • 如何向 UWP 项目添加 .NET dll 引用?

    我有几个适用于 NETv4 x 的 NET dll 项目 我将版本更改为 4 6 1 并重新构建 没有出现问题 当我尝试从 UWP 项目向它们添加引用时 出现错误 项目的目标是 NETCore 而文件引用的目标是 NET框架 这不是受支持的
  • 将 2D 数组映射到 1D 数组

    我想用一维数组来表示一个二维数组 函数将传递两个索引 x y 和要存储的值 这两个索引代表一维数组的单个元素 并相应地设置它 我知道一维数组需要具有 arrayWidth arrayHeight 的大小 但我不知道如何设置每个元素 例如 如
  • boost线程在中断时不打印退出消息

    我有这段代码用于执行三个线程 其中第二个线程应在按 Enter 时中断并打印退出消息 void input val DO STUFF return void process val DO STUFF try cout lt lt waiti
  • 为什么C Clock()返回0

    我有这样的事情 clock t start end start clock something else end clock printf nClock cycles are d d n start end 我总是得到输出 时钟周期是 0
  • 在 Windows Phone 上启动 pdf 文件时出现 System.Runtime.InteropServices.COMException

    我正在尝试使用我之前在另一个应用程序上使用过的以下工作代码打开 pdf 文件 但这一次 当流程到达此行时 我收到 System Runtime InteropServices COMException Windows System Laun
  • 我应该在单元测试中使用 AutoMapper 吗?

    我正在为 ASP NET MVC 控制器方法编写单元测试 这些控制器依赖于IMapper 我创建的用于抽象 AutoMapper 的接口 使用 Castle Windsor 通过构造函数注入传入 动作方法使用IMapper从领域对象映射到
  • Linq Where 本地计数器关闭在 VS watch 中的结果不同

    我尝试删除前 3 个元素array与 LinQWhere扩展功能 这是一个例子 var array new 1 2 3 4 5 6 7 8 9 var count 3 var deletedTest1 0 var test1 array W
  • 成员初始值设定项列表中的求值顺序是什么?

    我有一个带有一些参数的构造函数 我假设它们是按照列出的顺序初始化的 但在一种情况下 它们似乎是按相反的顺序初始化的 导致中止 当我反转参数时 程序停止中止 下面是我正在使用的语法的示例 a 之前需要初始化b 在这种情况下 你能保证这个初始化
  • for 循环 - 没有效果的语句

    由于某种原因 我收到错误 statement with no effect关于这个声明 for j idx j lt iter j increment printf from loop idx i int idx punc ctxt j 你
  • 为什么以下代码不允许我使用 fgets 获取用户输入但可以使用 scanf?

    这是一个更大程序的简短摘录 但该程序的其余部分无关紧要 因为我认为我能够隔离该问题 我怀疑这与我使用 fgets 的方式有关 我读过 最好使用 fgets 而不是 scanf 但我似乎无法让它在这里正常工作 当我使用以下代码时 程序不会给我
  • 抽象类和接口之间的区别[重复]

    这个问题在这里已经有答案了 可能的重复 接口与基类 https stackoverflow com questions 56867 interface vs base class 我不明白抽象类和接口之间的区别 我什么时候需要使用哪种字体
  • C#:如何使用 SHOpenFolderAndSelectItems [重复]

    这个问题在这里已经有答案了 有人可以举例说明如何使用 shell 函数吗SH打开文件夹并选择项目 http msdn microsoft com en us library bb762232 VS 85 aspx来自 C 我不太明白如何使用
  • 为什么 C 函数不能返回数组类型?

    我是 C 语言新手 想知道 为什么 C 函数不能返回数组类型 我知道数组名是数组第一个值的地址 而数组是 C 中的二等公民 您自己已经回答了这个问题 数组是二等公民 C 按值返回 数组不能按值传递 因此不能返回它们 至于为什么数组不能按值传
  • SSBO 是更大的 UBO?

    我目前正在 OpenGL 4 3 中使用 UBO 进行渲染 以将所有常量数据存储在 GPU 上 诸如材料描述 矩阵等内容 它可以工作 但是 UBO 的小尺寸 我的实现为 64kB 迫使我多次切换缓冲区 减慢渲染速度 我正在寻找类似的方法来存
  • C# - 为什么我需要初始化 [Out] 参数

    我有几个从本机 dll 导入的方法 使用以下语法 internal static class DllClass DllImport Example dll EntryPoint ExampleFunction public static e
  • 删除对象时指针自动指向空

    假设我有一个对象和其他几个不同类类型的对象中的 10 个指向它的指针 如果对象被删除 这些指针必须设置为空 通常我会将对象的类与具有指向它的指针的类互连 以便它可以通知它们它正在被删除 并且它们可以将它们的指针设置为空 但这也有一个负担 即
  • 在 unix 中编译 dhrystone 时出错

    我是使用基准测试和 makefile 的新手 我已经从下面的链接下载了 Dhrystone 基准测试 我正在尝试编译它 但我遇到了奇怪的错误 我尝试解决它 但没有成功 有人可以帮助我运行 dhrystone 基准测试吗 以下是我尝试编译的两
  • 宏观评价[重复]

    这个问题在这里已经有答案了 可能的重复 未定义的行为和序列点 https stackoverflow com questions 4176328 undefined behavior and sequence points 我无法理解以下宏
  • C++0x 中的新 unicode 字符

    我正在构建一个 API 它允许我获取各种编码的字符串 包括 utf8 utf16 utf32 和 wchar t 根据操作系统 可能是 utf32 或 utf16 新的 C 标准引入了新类型char16 t and char32 t没有这么
  • 当我读取 500MB FileStream 时出现 OutOfMemoryException

    我使用 Filestream 读取大文件 gt 500 MB 但出现 OutOfMemoryException 任何有关它的解决方案 我的代码是 using var fs3 new FileStream filePath2 FileMode

随机推荐

  • 旋转数组 LeetCode (189)

    问题如下 给定一个数组 将数组向右旋转 k 步 其中 k 为非负数 这是我的代码 class Solution public void rotate vector
  • NoSql 速成课程/教程 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我已经看到 NoSQL 在 SO 上出现了很多 并且我对why你会使用它 来自这里 维基百科等 这可能是由于缺乏对它是什么的具体和统一的定
  • Eclipse 在哪里存储更新站点列表?可以将其复制到另一个安装吗?

    我的 Eclipse 安装完全失败并且无法启动 因此我可能必须重新安装它 但这在升级到新的 Eclipse 版本时也相关 我不想寻找我安装的所有插件 那么 Eclipse 在哪里存储可用更新站点的列表呢 如果它不是纯文本形式 是否可以毫无问
  • Angular 2 中的嵌套模板[重复]

    这个问题在这里已经有答案了 我有一个组件
  • 在 ClosedXML 中应用多个过滤器 (SetAutoFilter)

    我通过 ClosedXML 对多个列应用过滤器 但是 仅应用最后一项 这些过滤器在单独使用时会起作用 我怎样才能应用所有这些 我在这里发现了类似的问题ClosedXML Excel 按多列中的值过滤行 https stackoverflow
  • Chrome 扩展页面 popup.html 无法调整大小

    所以我有这个 Chrome 扩展程序 可以从互联网上加载一些内容 基本上 用户单击弹出图标 然后后台页面中的一些 JavaScript 加载一些页面 从中解析图像并将其放入 popup html 页面中 问题是 popup html 没有调
  • 在 C# 中扩展枚举

    我想知道是否可以扩展 C 中的 Enum 类型来实现我的自定义 Enum GetValues type 并像 Enum GetMyCustomValues type 那样调用它 我正在尝试实现这样的事情 public static bool
  • 使用 C++ 命名参数习惯用法的更好方法?

    我一直在为 Windows 开发一个 GUI 库 作为个人业余项目 不希望有用 对于我的主窗口类 我设置了选项类的层次结构 使用命名参数惯用语 http www parashift com c faq lite named paramete
  • Microsoft Edge:本地/会话存储无法在新选项卡中工作

    我正在开发一个托管在 Azure 中的 Web 应用程序 我在 MS Edge 版本 20 10525 0 0 上尝试过 但遇到了以下问题 我有一个带有 target blank 的链接 可以在新选项卡中打开页面 在该链接的点击事件中 我将
  • 将日期字符串转换为正确的格式

    我收到服务器的响应 并且需要将日期字符串转换为日期 2017 年 6 月 29 日星期四 07 15 25 0000 我正在尝试将字符串转换为人类可读的格式 谁能建议如何将此字符串转换为日期 您需要将日期字符串解析为Date对象使用Date
  • 可捕获的致命错误:类 mysqli 的对象无法转换为字符串

    所以我有一个问题 我对 PHP 非常陌生 并且在更新数据库上的字符串时遇到问题 它抛出了这个错误 Catchable fatal error Object of class mysqli Could not be Converted to
  • 获取类型的默认构造函数的最有效方法

    获取 System Type 的默认构造函数 即不带参数的实例构造函数 的最有效方法是什么 我正在思考下面的代码 但似乎应该有一种更简单更有效的方法来做到这一点 Type type typeof FooBar BindingFlags fl
  • 如何从对象中深度删除空值、空对象和空数组

    我有一个看起来像这样的对象 var myObject a b c d 2 e 2 f g h i null 2 我想删除空值和空对象 数组和对象 使其看起来像 a c d 2 e 2 i 2 该函数应删除空值 空对象和空数组 有什么优雅的方
  • 找出远程服务器上git的版本

    我正在本地计算机上寻找 git 命令 我可以运行该命令来查找远程服务器上运行的 git 版本 如果这可能的话 现代 git 服务器 始于git 1 7 12 1 https github com git git commit ff5effd
  • 运行Hadoop时如何避免OutOfMemoryException?

    我正在运行一个超过 1 5 TB 数据的 Hadoop 作业 并进行大量模式匹配 我有几台每台 16GB RAM 的机器 我总是得到OutOfMemoryException使用这些数据来完成这项工作 我正在使用 Hive 我想知道如何最佳设
  • 多行函数调用的左括号必须是该行的最后一个内容

    我在 PHP 文件中写入以下代码 public function ScriptsStyles wp enqueue style fontawesome plugins url css font awesome css FILE array
  • WPF:“名称”和“x:名称”之间有什么区别? [复制]

    这个问题在这里已经有答案了 可能的重复 在 WPF 中 x Name 和 Name 属性之间有什么区别 https stackoverflow com questions 589874 in wpf what are the differe
  • Android CoroutineScope 完成后自动取消

    我想知道是否coroutineScope工作完成后将自动取消 假设我创建了一个coroutineScope在自定义类中而不是 ViewModel类或Fragment Activity class class MyClass private
  • firebase存储cors奇怪的行为

    我正在构建一个应用程序 让用户看到一组缩小的图像 然后按 确定 让应用程序下载所有原始文件 将它们放入 zip 文件中并发送 zip 文件 该应用程序使用polymer polymerfire firebase 包括存储 在上传图像的过程中
  • 组合两个 Linq lambda 表达式

    Expression