【问题标题】:Linq query throws NullReferenceException when pulling data from SQLite, why?从 SQLite 提取数据时,Linq 查询抛出 NullReferenceException,为什么?
【发布时间】:2017-10-21 08:03:51
【问题描述】:

我正在尝试使用以下查询从 SQLite 数据库中提取数据:

DateTime Dzien = new DateTime(ticks ?? 0);
    var assinged = Data.Tasks.ToList();
    var assign =  assinged.Where(t => t.AssignedId ==
                              Data.AssignedTasks.FirstOrDefault(d => d.Date.Date == Dzien.Date).Id).ToList();

但它会抛出异常:

NullReferenceException:对象引用未设置为对象的实例。 PiCoreSQLite.Controllers.HomeController+c__DisplayClass3_0.b__0(Tasks t) 在 HomeController.cs,第 37 行

Data 对象是一个数据库上下文,Tasks 是一个包含 Tasks 对象的 DbSet。

我尝试删除 ToList() 但查询没有返回任何内容。但是,在 asp.net .cshtml 视图中使用类似查询时,它确实有效并返回数据:

 @{
    var zrobione =
        from completed in Model.Item1.Where(t => t.AssignedId == 
        Model.Item3.FirstOrDefault(d => d.Date.Date == DateTime.Today).Id)
        group completed by completed.Categories;
}

我尝试用流畅的语法重写查询,它仍然抛出异常。

我的问题是:为什么会抛出异常以及如何解决?

【问题讨论】:

    标签: c# asp.net linq linq-to-sql


    【解决方案1】:

    为什么会抛出这个异常?

    问题是由以下语句引起的:

    Data.AssignedTasks.FirstOrDefault(d => d.Date.Date == Dzien.Date)
    

    FirstOrDefault 方法返回您应用此方法的序列中的第一个项目,该项目满足您在此方法中传递的谓词,在这种情况下,谓词如下:

    d => d.Date.Date == Dzien.Date
    

    如果未找到任何此类项目,则返回 null(更一般地,返回您正在查找的对象类型的默认值。所以,如果您正在寻找int 默认值为 0。在 reference type 的情况下,默认值为 null)。

    话虽如此,很明显返回了 null,然后您尝试访问空引用的 Id 属性...因此您收到此错误消息。

    我们该如何处理?

    一种方法可能如下:

    var assign =  assinged.Where(t => t.AssignedId ==
                                    (Data.AssignedTasks
                                         .FirstOrDefault(d => d.Date.Date == Dzien.Date)?.Id ?? -1))
                          .ToList();
    

    在上面的代码中我做了一个假设AssignedId 只取正值或零值。如果不是这种情况,您可以适当地处理。

    以上是如何工作的?

    正如我们已经提到的,FirstOrDefault 将返回对满足您传递的谓词或null 的第一个找到的对象的引用。因此,为了安全起见,我们使用空条件运算符?.。如果你得到任何非空引用,你可以安全地阅读Id,否则这样做毫无意义,结果是null。然后应用空合并运算符??。此运算符在不为 null 时返回左侧值,否则返回右侧值。

    【讨论】:

      【解决方案2】:

      首先,您需要确定究竟是什么引发了异常。将您的代码分成简单的小步骤并进行调试。失败的地方会告诉你如何妥善处理。

      另外,值得注意的是,您的代码的第一个示例根本不是 LINQ to SQL,而第二个示例是。这就是区别,也是它们工作方式不同的原因之一。顺便说一句,这应该是意料之中的。

      Data.AssignedTasks.FirstOrDefault(d => d.Date.Date == Dzien.Date) 很可能返回 null,然后将 Id 拉出会引发异常。在第二个示例中,整个表达式被转换为 SQL 查询,这就是它正常工作的原因。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-27
        • 2014-03-07
        • 2014-11-25
        • 2015-01-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多