[英]How do I rewrite this Linq query to avoid using FirstOrDefault?
我有一个Quotes表,它有一个相关的Revisions表。 一个基本的业务规则是报价必须至少有一个版本,但可能有很多。 我有一个像这样开始的查询......
var revisions = ctx.Quotes
.Select(q => q.Revisions.OrderByDescending(r => r.RevisionNumber).FirstOrDefault())
// Do things with the revisions here...
目的是获取每个引用的最新版本,然后从中选择一些信息。
这样可以正常工作,除了我们在数据库中有一个没有任何修订的流氓引用。 在上面显示的代码下方的某处,我得到了一个例外......
转换为值类型'System.Int32'失败,因为实现的值为null。 结果类型的泛型参数或查询必须使用可空类型
这花了一个时间来调试,因为我们没有意识到它是由流氓引用引起的。 理想情况下,查询的第二行将使用First()而不是FirstOrDefault(),它会在那里抛出异常,立即显示问题的根源。 但是,Entity Framework不允许您使用First()或Single()mid-query,这就是我们使用FirstOrDefault()的原因。
没有完全重写查询,即首先查询Revisions表并导航回到Quote(由于其他原因会很痛苦),是否有一种简单的方法来防范这种情况? 在这种情况下,我通过将第一行更改为...来修复它
var revisions = ctx.Quotes.Where(q => q.Revisions.Any())
...但这是针对这种情况的具体修复,并且在我们最终发现问题后才明显。 理想情况下,我想要一个通常适用的解决方案。
要获得内连接语义,IMO一般替换Select
/ OrderBy
/ FirstOrDefault
是SelectMany
/ OrderBy
/ Take(1)
:
var revisions = ctx.Quotes
.SelectMany(q => q.Revisions.OrderByDescending(r => r.RevisionNumber).Take(1))
// Do things with the revisions here...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.