gpt4 book ai didi

c# - 如何重写此 Linq 查询以避免使用 FirstOrDefault?

转载 作者:行者123 更新时间:2023-11-30 14:07:14 25 4
gpt4 key购买 nike

我有一个 Quotes 表,它有一个关联的 Revisions 表。一个基本的业务规则是报价必须至少有一个修订版,但也可以有多个修订版。我有一个这样开始的查询...

var revisions = ctx.Quotes
.Select(q => q.Revisions.OrderByDescending(r => r.RevisionNumber).FirstOrDefault())
// Do things with the revisions here...

目的是获取每条报价的最新修订,然后从中选择一些信息。

这工作正常,除了我们在数据库中有一个没有任何修订的流氓报价。在上面显示的代码下方的某个地方,我遇到了一个异常......

The cast to value type 'System.Int32' failed because the materialized value is null. Either the result type's generic parameter or the query must use a nullable type

这花了很长时间来调试,因为我们没有意识到它是由恶意引用引起的。理想情况下,查询的第二行应该使用 First() 而不是 FirstOrDefault(),这会立即引发异常,立即显示问题的根源。但是, Entity Framework 不允许您在查询中使用 First() 或 Single(),这就是我们使用 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...

关于c# - 如何重写此 Linq 查询以避免使用 FirstOrDefault?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42353640/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com