【发布时间】:2017-02-21 04:39:53
【问题描述】:
我有一个 Quotes 表,它有一个关联的 Revisions 表。一个基本的业务规则是报价必须至少有一个修订版,但可能有很多。我有一个这样开头的查询...
var revisions = ctx.Quotes
.Select(q => q.Revisions.OrderByDescending(r => r.RevisionNumber).FirstOrDefault())
// Do things with the revisions here...
目的是获取每个报价的最新版本,然后从中选择一些信息。
这工作正常,除了我们在数据库中有一个没有任何修订的流氓报价。在上面显示的代码下方的某个地方,我遇到了一个异常......
转换为值类型“System.Int32”失败,因为物化了 值为空。结果类型的泛型参数或查询 必须使用可空类型
调试需要很长时间,因为我们没有意识到这是由流氓引用引起的。理想情况下,查询的第二行将使用 First() 而不是 FirstOrDefault(),这会在此处引发异常,立即显示问题的根源。但是,Entity Framework 不允许您使用 First() 或 Single() 中间查询,这就是我们使用 FirstOrDefault() 的原因。
如果不完全重写查询,即首先查询 Revisions 表并导航回 Quote(由于其他原因会很痛苦),是否有一种简单的方法来防止这种情况发生?在这种情况下,我通过将第一行更改为...来修复它。
var revisions = ctx.Quotes.Where(q => q.Revisions.Any())
...但这是针对这种情况的特定修复,并且仅在我们最终发现问题后才明显。理想情况下,我想要一个普遍适用的解决方案。
【问题讨论】:
-
您显示的查询部分似乎很好。知道它是如何进行的会很有趣。怀疑您将生成的修订版投影到提取整数的东西中。请提供整个查询。
-
@tinudu 正如我解释的那样,我展示的查询部分是问题所在,因为它假设每个报价都有一个修订版(它应该有),并且 FirstOrDefault() 是返回默认值,导致问题降低。不管后面发生了什么,我什么都做不了,只要查询有要枚举的东西,它就会抛出异常
标签: c# entity-framework linq