1

我正在使用实体框架,并且我有一个 COMMENT 实体。COMMENT 有一个 DATEMODIFIED 属性,它是一个可空日期。我正在尝试构建一个按日期过滤评论的查询,因此我创建了一个 startDate 对象,并执行以下操作:

Dim q As ObjectQuery(Of COMMENT) = _ 
   (From c In model.COMMENT Select c)

If startDate.HasValue Then
   q = q.Where(Function(c) startDate.Value <= c.DATEMODIFIED)
End If

问题是 q.toList() 没有返回任何评论,即使我认为它应该。数据库中的所有注释都有 DATEMODIFIED 值,即使我将 DateTime.MinValue 作为 startDate 传递,查询仍然不匹配任何实体。

我在 If-Statement 之前设置了一个断点,并使用 Visual Studio Watch Window 来尝试查看发生了什么:

q.ToList()(0).DATEMODIFIED    'Returns the expected date 
startDate.Value               'Returns the expected date 
startDate.Value <= q.ToList()(0).DATEMODIFIED    'Returns True...

但是一旦它到达 q = q.Where(predicate) 部分,q.ToList() 就不再返回任何条目。我难住了。

4

1 回答 1

2

更新:糟糕,我忘记了,使用 LINQ to Entities,所有 WHERE 表达式都被转换为 SQL 调用,而不是在代码中进行后处理——因此下面的调试建议不一定有效。

因此,我将首先针对您的数据库运行相同的生成 SQL 语句,并验证您的 Entity Framework 提供程序生成的 SQL 是否实际上返回了您期望的数据。@Craig Stuntz 上面的评论绝对是正确的,可以帮助您做到这一点。一旦你有了参数化的 SQL,我会尝试直接从你的代码中执行那个 SQL(使用System.Data.OracleClient)并验证你实际上从那个查询中得到了结果。请记住注入您从中获得的相同参数值ObjectQuery.Parameters。或者,您可以自己粘贴参数并从您选择的 Oracle 客户端应用程序执行查询。

如果您没有从该 SQL 获得结果,则可能是 devArt 的提供程序错误地构建了查询。

您可以忽略下面的内容,因为它适用于排除 LINQ-to-Objects 而不是 LINQ-to-Entities

诊断此问题的一些想法:

首先,在你的观察窗口中试试这个:

q.Where(Function(c) startDate.Value <= c.DATEMODIFIED).Count()

我假设这将返回零,但值得消除许多其他变量以确保您真的没有得到任何结果。

接下来,我将尝试以不同的方式定义您的 LINQ 查询——不要单独附加 Where(),而是尝试使用两个查询,如下所示:

Dim q As ObjectQuery(Of COMMENT)
If startDate.HasValue Then
    q = (From c In model.COMMENT Where startDate.Value <= c.DATEMODIFIED Select c)
Else
    q = (From c In model.COMMENT Select c)
End If

如果这可行,那么将 Where 子句附加到现有 LINQ 查询的方式有问题——可能是 DBMS 的实体框架提供程序中的错误?

如果这仍然不起作用,我要进行诊断的下一步将是验证 where 子句中的代码是否被调用,并检查传递给该代码的值。我不知道如何像在 C# 中那样在 VB 中设置行内断点,但是您可以轻松(临时)将 lambda 重构为一个单独的函数并在那里设置断点。像这样:

Sub Main()
    Dim testDate As Date = New Date(2005, 1, 1)
    Dim x = New List(Of Date?)
    x.Add(New Date(2009, 1, 1))
    x.Add(New Date(2008, 1, 1))
    x.Add(New Date(2007, 1, 1))
    x.Add(New Date(2006, 1, 1))
    x.Add(New Date(2005, 1, 1))
    x.Add(New Date(2004, 1, 1))
    x.Add(New Date(2003, 1, 1))
    x.Add(New Date(2002, 1, 1))
    x.Add(New Date(2001, 1, 1))
    Dim y = From n In x Select n
    y = y.Where(Function(val) test(val, testDate))
    Dim z = y.ToArray()
End Sub

Function test(ByVal date1 As Date, ByVal date2 As Date) As Boolean
    test = date1 >= date2
End Function

检查发送到比较函数的值——它们有效吗?比较是否返回您期望的结果?

于 2009-11-04T14:07:00.957 回答