ObjectQuery.Where 中的日期时间比较
我正在使用实体框架,并且有一个 COMMENT 实体。 COMMENT 有一个 DATEMODIFIED 属性,它是一个可为 Null 的日期。我正在尝试构建一个按日期过滤 COMMENT 的查询,因此我创建了一个 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 语句之前设置了一个断点,并使用 Visual Studio 监视窗口来尝试查看发生了什么:
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() 就不再返回任何条目。我很困惑。
I'm using Entity Framework, and I have a COMMENT entity. A COMMENT has a DATEMODIFIED property, which is a Nullable Date. I'm trying to build a query that will filter COMMENTs by date, so I create a startDate object, and do the following:
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
The problem is that q.toList() is not returning any comments, even though I think it should. All comments in the database have DATEMODIFIED values, and even if I pass in DateTime.MinValue as the startDate, the query still doesn't match any entities.
I set a breakpoint before the If-Statement and used the Visual Studio Watch Window to try and see what's going on:
q.ToList()(0).DATEMODIFIED 'Returns the expected date
startDate.Value 'Returns the expected date
startDate.Value <= q.ToList()(0).DATEMODIFIED 'Returns True...
But once once it hits the q = q.Where(predicate) part, q.ToList() no longer returns any entries. I'm stumped.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
更新:哎呀,我忘记了,使用 LINQ to Entities,所有 WHERE 表达式都被转换为 SQL 调用,而不是在代码中进行后处理 - 因此下面的调试建议不一定有效。
因此,我首先对数据库运行相同的生成的 SQL 语句,并验证实体框架提供程序生成的 SQL 是否确实返回了您期望的数据。 @Craig Stuntz 上面的评论绝对是正确的,可以帮助你做到这一点。获得参数化 SQL 后,我将尝试直接从您的代码执行该 SQL(使用 System.Data.OracleClient)并验证您是否确实从该查询中获取了结果。请记住注入与从
ObjectQuery.Parameters
获取的相同参数值。或者,您可以自己粘贴参数并从您选择的 Oracle 客户端应用程序执行查询。如果您没有从该 SQL 中获得结果,则 devArt 的提供程序可能错误地构建了查询。
您可以忽略下面的内容,因为它适用于 LINQ-to-Objects 的故障排除,但不适用于 LINQ-to-Entities
诊断此问题的一些想法:
首先,在监视窗口中尝试此操作:
我假设这将返回零,但值得消除许多其他变量以确保您确实没有得到任何结果。
接下来,我尝试以稍微不同的方式定义您的 LINQ 查询 - 不要单独附加Where(),而是尝试使用两个查询,如下所示:
如果这有效,则附加Where子句的方式有问题到您现有的 LINQ 查询 - 也许是您的 DBMS 实体框架提供程序中的错误?
如果这仍然不起作用,我要诊断的下一步是验证 where 子句中的代码是否正在被调用,并检查传递到该代码中的值。我不知道如何像在 C# 中那样在 VB 中设置行内断点,但您可以轻松(暂时)将 lambda 重构为一个单独的函数并在那里设置断点。像这样:
检查发送到比较函数中的值——它们是否有效?比较结果是否符合您的预期?
UPDATE: Oops, I forgot that, with LINQ to Entities, all WHERE expressions are translated into SQL calls instead of being post-processed in code-- so the debugging suggestions below won't necessarily work.
Therefore, I'd start by running the same generated SQL statement against your database, and validating whether the SQL generated by your Entity Framework provider is actually returning the data you expect. @Craig Stuntz's comment above is definitely on the right track here to help you do this. Once you have the parameterized SQL, I'd try executing that SQL directly from your code (using
System.Data.OracleClient
) and validating that you actually get results back from that query. Remember to inject the same parameter values that you get fromObjectQuery.Parameters
. Alternatively, you could stick the parameters in yourself and execute the query from your Oracle client app of choice.If you don't get results from that SQL, then it's possible that devArt's provider is building the query incorrectly.
you can ignore what's below here, since it applies to troubleshooting LINQ-to-Objects but not LINQ-to-Entities
Some ideas to diagnose this:
first, try this in your watch window:
I'm assuming this will return zero, but it's worth eliminating as many other variables to make sure you're really not getting any results.
Next, I'd try is to define your LINQ query a bit differently-- instead of appending the Where() separately, try using two queries, like this:
If this works, then there's something wrong with how the Where clause is being attached to your existing LINQ query-- perhaps a bug in your DBMS's entity-framework provider?
If that still doesn't work, the next step I'd take to diagnose would be to verify that the code inside the where clause is being called, and checking the values passed into that code. I couldn't figure out how to set intra-line breakpoints in VB like one can do in C#, but you can easily (temporarily) refactor your lambda into a separate function and set the breakpoint there. Like this:
Check the values being sent into your comparison function-- are they valid? Does the comparison return what you expect it to?