更新:糟糕,我忘记了,使用 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
检查发送到比较函数的值——它们有效吗?比较是否返回您期望的结果?