如何修复Enumerable.ToDictionary中发生的ArgumentNullException(或NullReferenceException?(C# ASP.NET MVC)

How to fix an ArgumentNullException (or NullReferenceException?) occurring in Enumerable.ToDictionary? (C# ASP.NET MVC)

提问人:Ethan 提问时间:7/10/2021 最后编辑:James ZEthan 更新时间:7/10/2021 访问量:414

问:

我有一个正在发生的异常,但我不太明白它是如何发生的。我将不胜感激有关如何修复它的任何提示,或有关如何更好地理解错误发生原因的建议。

背景信息

  • 该错误已记录到我们的错误数据库中,不幸的是,我自己无法重现该错误。
  • 此错误发生在 24/7 全天候运行的仪表板应用程序中,并且它每分钟尝试刷新一次数据。因此,此错误在过去几周内多次发生。虽然这并不是一个紧迫的问题,因为仪表板不久后会重新尝试刷新数据,但令我感到困扰的是,我无法修复它。

错误

这是记录的异常消息:查找它,这似乎是由 NullReferenceException 引起的。但是,异常发生在 中,根据文档,它只会引发 ArgumentNullException。因此,我对发生哪个错误、如何发生以及为什么发生感到困惑。Object reference not set to an instance of an object.Enumerable.ToDictionary()

下面是堆栈跟踪的相关部分。

   at PackerVM.<>c.<GetData>b__32_3(OrderDetail orderDetail) in PackerVM.cs:line 72
   at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
   at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector)
   at PackerVM.GetData() in PackerVM.cs:line 65

代码

这是发生错误的代码。

_orderDetails = miiDb.OrderDetails  // OrderDetails is a DbSet<OrderDetail>
    .Where(orderDetail => orderDetail.Department == "MOLDING" && orderDetail.Location != null)
    .GroupBy(orderDetail => orderDetail.Location)
    .Select(orderDetails => orderDetails.OrderByDescending(w => w.ReleaseState)
        .ThenBy(orderDetail => orderDetail.Sequence)
        .ThenBy(orderDetail => orderDetail.PlannedStart)
        .FirstOrDefault())
    .ToDictionary(orderDetail => orderDetail.Location, orderDetail => new PackerPressData()
    {
        Location = orderDetail.Location,
        MachineStatus = orderDetail.MachineStatus,
        ReleaseState = orderDetail.ReleaseState,
        Tool = orderDetail.Tool,
        PartNumber = orderDetail.PartNumber
    });

以下是有关堆栈跟踪中行号的一些其他详细信息:

第 72 行引用了这部分代码:.ToDictionary(orderDetail => orderDetail.Location, orderDetail => new PackerPressData()

第 65 行引用了这部分代码:_orderDetails = miiDb.OrderDetails

我的进度

错误发生在 中,因此我首先查找了 Microsoft 文档中的 Enumerable.ToDictionary,这就是我确定错误是 ArgumentNullException 的方式。如前所述,该消息似乎对应于 NullReferenceException,导致我的困惑。Enumerable.ToDictionary

这基本上是我卡住的地方,因为我无法重现这个问题。正如我所提到的,数据经常更新,所以我的测试可能还没有运行足够长的时间再次遇到它。

我尝试在本地测试时手动添加检查,以查看语句前面的语句生成的任何 OrderDetails 是否为 null,但没有一个是 null。.Select().ToDictionary()

我唯一能想到的就是在 and 语句之间添加一个 Where 子句:,但我不相信这会解决问题的根本原因,因为我不完全理解此时的 OrderDetail 如何首先为 null。.Where(orderDetail => orderDetail != null).Select().ToDictionary()

顶级域名

Enumerable.ToDictionary() 似乎正在生成 ArgumentNullException,但保存到错误数据库的错误消息对应于 NullReferenceException。此外,我不明白用于生成 Dictionary 对象的对象如何在代码中的那个点为 null。

C# asp.net ASP.NET-MVC NullReferenceException 参数NullException

评论

0赞 Tim Schmelter 7/10/2021
它与 无关,这是肯定的,因为正如您所说,如果 是 ,它将抛出一个 not a 。这正是执行查询的位置,因此在访问对象的属性之前,在查询中的某个位置。ToDictionaryArgumentNullExceptionNullReferenceExceptionsourcenullnull
2赞 paulsm4 7/10/2021
建议:1)编写一个小型的独立测试程序。复制/粘贴上面的 LINQ 查询。2)创建一些返回一行或多行的测试数据。我怀疑”。ToDictionary()“将正常工作。3) 现在创建一些不同的测试数据,这些数据返回 NO 行。4)我怀疑你会重现你的错误。换句话说,如果你尝试会发生什么”。ToDictionary()“在空集上?5)如果我的预感是正确的,只需将LINQ拆分为两个表达式即可:)_orderDetails = miiDb.OrderDetailsObject reference not set to an instance of an object
0赞 Tim Schmelter 7/10/2021
@paulsm4:如果源序列是 ,上面的所有 Linq 方法都会抛出一个而不是一个。除此之外,只有当它被声明为字段或非公共时,它才为 null,这似乎并非如此,因为 OP 说它几乎总是在工作。如果现在有行,则字典应为空。ArgumentNullExceptionNullReferenceExceptionnullDbSet
1赞 Tim Schmelter 7/10/2021
我猜有一个空实体,无论出于何种原因,可能是从某个地方添加的
0赞 lidqy 7/10/2021
如果将 替换为 会发生什么情况。异常类型和消息是否更改?FirstOrDefault 有可能返回 null 引用(尽管我认为所有组都至少有一个元素,所以它不应该返回 null......FirstOrDefaultFirst

答: 暂无答案