带有 lambda 表达式的 LINQ where 子句,该表达式具有 OR 子句和返回不完整结果的 null 值

2023-12-24

简而言之问题

我们在Where子句中使用了一个lambda表达式,它没有返回“预期”结果。

快速总结

在analysisObjectRepository 对象中,某些对象也在名为Parent 的属性中包含父关系。我们正在查询这个analysisObjectRepository以返回一些对象。

detail

下面的代码应该做的是,返回包含 ID 值的特定对象的根、第一个子对象(直接子对象)和孙子对象。

在下面的代码中,常识表明,使 3 个单独的 OR 条件中的任何一个为 true 的所有结果都应该像结果中一样返回。

List<AnalysisObject> analysisObjects = 
    analysisObjectRepository
        .FindAll()
        .Where(x => x.ID               == packageId ||
                    x.Parent.ID        == packageId || 
                    x.Parent.Parent.ID == packageId)
        .ToList();

但上面的代码只返回子对象和孙子对象,而不返回根对象(具有 null Parent 值),这使得

x.ID == packageId

条件为真。

仅构成第二个的对象

x.Parent.ID == packageId

第三个

x.Parent.Parent.ID == packageId

条款被退回。

如果我们只用下面的代码编写返回根对象的代码,它就会被返回,所以我们完全确定analysisObjectRepository包含所有对象

List<AnalysisObject> analysisObjects = 
    analysisObjectRepository
        .FindAll()
        .Where(x => x.ID == packageId )
        .ToList();

但是,当我们将其重写为委托时,我们得到了预期的结果,返回所有预期的对象。

List<AnalysisObject> analysisObjects = 
    analysisObjectRepository
        .FindAll()
        .Where(delegate(AnalysisObject x) 
        { 
            return 
              (x.ID == packageId) || 
              (x.Parent != null && x.Parent.ID == packageId) || 
                  (x.Parent != null && 
                   x.Parent.Parent != null && 
                   x.Parent.Parent.ID == packageId); })
        .ToList();

question

我们是否在 lambda 表达式中遗漏了某些内容?这是一个非常简单的三部分 OR 条件,我们认为任何使三个条件中的任何一个为 true 的对象都应该被返回。我们怀疑具有 null Parent 值的根对象可能会导致问题,但无法准确地弄清楚。

任何帮助都会很棒。


您的第二个委托不是以匿名委托(而不是 lambda)格式重写第一个委托。看你的条件了。

First:

x.ID == packageId || x.Parent.ID == packageId || x.Parent.Parent.ID == packageId

Second:

(x.ID == packageId) || (x.Parent != null && x.Parent.ID == packageId) || 
(x.Parent != null && x.Parent.Parent != null && x.Parent.Parent.ID == packageId)

对 lambda 的调用将引发任何异常x其中 ID 不匹配且父级为 null 或不匹配且祖父母为 null。将 null 检查复制到 lambda 中,它应该可以正常工作。

对问题发表评论后编辑

如果你的原始对象不是List<T>,那么我们无法知道返回类型是什么FindAll()是,以及这是否实现了IQueryable界面。如果确实如此,那么这可能可以解释这种差异。因为 lambda 可以在编译时转换为Expression<Func<T>> 但匿名代表不能,那么您可能正在使用的实现IQueryable使用 lambda 版本时,但使用匿名委托版本时使用 LINQ-to-Objects。

这也可以解释为什么你的 lambda 没有引起NullReferenceException。如果您要将 lambda 表达式传递给实现IEnumerable<T> but not IQueryable<T>, lambda 的运行时求值(与其他方法没有什么不同,无论是否匿名)都会抛出NullReferenceException当它第一次遇到一个物体时ID不等于目标并且父母或祖父母为空。

添加于 2011 年 3 月 16 日上午 8:29(美国东部时间)

考虑以下简单示例:

IQueryable<MyObject> source = ...; // some object that implements IQueryable<MyObject>

var anonymousMethod =  source.Where(delegate(MyObject o) { return o.Name == "Adam"; });    
var expressionLambda = source.Where(o => o.Name == "Adam");

这两种方法产生完全不同的结果。

第一个查询是简单版本。匿名方法产生一个委托,然后将其传递给IEnumerable<MyObject>.Where扩展方法,其中的全部内容source将针对您的委托进行检查(使用普通编译代码在内存中手动检查)。换句话说,如果您熟悉 C# 中的迭代器块,则类似于执行以下操作:

public IEnumerable<MyObject> MyWhere(IEnumerable<MyObject> dataSource, Func<MyObject, bool> predicate)
{
    foreach(MyObject item in dataSource)
    {
        if(predicate(item)) yield return item;
    }
}

这里的重点是您实际上正在执行过滤在记忆中在客户端。例如,如果您的源是一些 SQL ORM,则不会有WHERE查询中的子句;整个结果集将被带回客户端并进行过滤there.

第二个查询使用 lambda 表达式,被转换为Expression<Func<MyObject, bool>>并使用IQueryable<MyObject>.Where()扩展方法。这会产生一个对象,其类型也为IQueryable<MyObject>。所有这些都在通过之后起作用表达到底层提供商。这就是为什么你没有得到NullReferenceException。这完全取决于查询提供者如何翻译表达式(它不是一个可以调用的实际编译函数,而是一个表达式的表示)logic使用对象的表达式)转换为它可以使用的东西。

一个简单的方法来了解区别(或者,至少,有is)一个区别,就是调用AsEnumerable()在您致电之前Where在 lambda 版本中。这将强制您的代码使用 LINQ-to-Objects(意味着它在IEnumerable<T>就像匿名委托版本一样,而不是IQueryable<T>就像当前的 lambda 版本一样),并且您将得到预期的异常。

TL;DR 版本

简而言之,您的 lambda 表达式正在被转换为针对您的数据源的某种查询,而匿名方法版本正在评估entire内存中的数据源。无论将 lambda 转换为查询,所做的任何操作都不代表您期望的逻辑,这就是为什么它不会产生您期望的结果。

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

带有 lambda 表达式的 LINQ where 子句,该表达式具有 OR 子句和返回不完整结果的 null 值 的相关文章

随机推荐

  • RStudio 服务器导出功能背后的代码

    我目前正在使用 RStudio serverLinux redhat RStudio server 的一个很好的功能是我可以从服务器导出到我的Windows桌面 有谁知道导出下拉菜单背后的代码 导出功能可以通过以下方式找到Files tab
  • 为什么我从 npm 运行 Jest 时得到 0 覆盖率?

    我正在尝试使用 Jest 获取单个 Vue 组件的代码覆盖率数字 假设我的组件是 var www html path to Component vue其对应的单元测试文件为 var www html path to tests unit C
  • 真正的转义字符串与绑定参数

    在 php 中 使用 mysqli 有什么区别 哪个更好以及为什么 我有一个用真正的转义字符串编写的整个项目 是否有必要转换为面向对象的准备语句 从程序员的角度来看 手动转义值与 PDO 实现的参数化 准备语句之间的区别在于分离程度 自动化
  • 如何仅签署 XML 的特定部分

    我试图通过仅签署 xml 的一部分来进行一些 XML 签名 但是经过多次搜索后我无法找到解决方案 我正在使用 java 通过 Xpath2 转换和 EXCLUSIVE 规范化对 XML 进行签名 如果我有以下 XML
  • JavaScript 是否提供高分辨率计时器?

    JavaScript 是否提供高分辨率计时器 我从头开始编写了一些游戏引擎 有些是用 C 编写的 有些是用 Java 编写的 有些是用 Flash 编写的 在动画和交互式图形方面 我始终遵循相同的基本模型 使用以下设计创建一个基本类 结构
  • Rails“公共”文件夹中文件的自定义内容类型

    对于存储在 ruby on rails 应用程序的 public 文件夹中的资产 是否可以在运行 script server 时更改 Content Type 例如 我正在尝试创建一个支持离线模式的 HTML5 应用程序 并且有一个 off
  • SSIS - 插入新行、更新行

    检查哪一行已更改以及哪些行已存在的 最佳 或推荐方法是什么 我发现了一些文章 但我不确定这些方法是否是最好的 http www ssistalk com 2007 03 09 ssis using a checksum to define
  • Jmeter - 嵌入变量和 $ 的正则表达式问题

    问候 在 Jmeter 的正则表达式组件中 当表达式同时具有变量和文字 时 我遇到了一个问题 它总是返回失败 当我用硬编码值替换变量时 它工作得很好 我已经验证该变量在上次调用中返回了预期值 失败的表达 变量和文字
  • MVC 6 中 @Json.Encode 或 @Json.Decode 方法在哪里?

    相当于MVC5的什么 Json EncodeMVC6 中的方法 在 MVC5 中 我们可以在视图中访问这些方法 但我找不到任何可以从 MVC 6 视图访问的方法 如果 MVC6 中已经有内置功能 我不想编写辅助方法 经过一番查找 找到了 i
  • NSDate、NTP 和载波时间

    我刚刚在文档中读到 Cocoa 根据网络时间协议 NTP 标准来实现时间 该标准基于协调世界时 我正确地假设 OSX 正在与互联网同步 对吗 iOS 设备呢 相同的 NSObject NSDate NSCalendar 等 是否也与互联网同
  • lambda 捕获变量的规则

    例如 class Example public explicit Example int n num n void addAndPrint vector
  • 如何在AutoMapper中全局使用Ignore?

    这是现在的样子 DestinationA 和 DestinationB 派生自某个 DestinationBase 类 我需要忽略所有这些派生类的一些常见属性 无论如何都可以应用这些忽略选项globally无需对所有派生目标类重复 Mapp
  • 是否可以使用 play Framework 2 来美化 scala 模板?

    使用 Play Framework 2 我注意到渲染的 Scala HTML 模板不喜欢缩进 if or for 因此 例如 类似的事情 ul for test lt tests li test name li ul 会有额外的不需要的空间
  • Python 和 .NET 集成

    我目前正在研究 python 因为我真的很喜欢它的文本解析功能和 nltk 库 但传统上我是一名 Net C 程序员 我不认为 IronPython 对我来说是一个集成点 因为我正在使用 NLTK 并且可能需要将该库移植到 CLR 我看过一
  • Alamofire 会自动存储 cookie 吗?

    我是新来的阿拉莫菲尔所以我很抱歉 如果这是一个菜鸟问题 该框架自动存储cookie 这是因为我有一个像这样的简单请求 Alamofire request POST loginURL parameters fb id fbId fb acce
  • 开发 PowerBI 视觉效果

    我发现很难从头开始开发 PowerBI 视觉对象 我正在读书wiki https github com Microsoft PowerBI visuals core wiki guide https github com Microsoft
  • 对于 Silverlight 中 SaveFileDialog 中缺少 DefaultFileName 的最优雅的解决方法是什么?

    Silverlight 中的 SaveFileDialog 缺少 DefaultFileName 属性 导致用户必须在从 Silverlight 应用程序下载每个文件时手动输入文件名 这非常烦人 对此有很多批评 请参阅Silverlight
  • 有没有 Java Applet 的插件框架?

    我们有一个作为 applet 或 Java Web Start 运行的大型 Java 应用程序 而且它越来越大 通常 用户只需要一小部分课程 因为Java不知道在哪个jar文件中可以找到哪个类 所以它会加载所有jar文件 直到找到该类 如果
  • Gradle 中的 transitive = true 到底做了什么(w.r.t. crashlytics)?

    Gradle 是做什么的transitive true究竟做什么 从中并不清楚Gradle 文档 https docs gradle org current userguide dependency management html 这是在以
  • 带有 lambda 表达式的 LINQ where 子句,该表达式具有 OR 子句和返回不完整结果的 null 值

    简而言之问题 我们在Where子句中使用了一个lambda表达式 它没有返回 预期 结果 快速总结 在analysisObjectRepository 对象中 某些对象也在名为Parent 的属性中包含父关系 我们正在查询这个analysi