这种事情一直困扰着我,所以我想我会向你们这些聪明人寻求“更好的方法”。
我有一个查询,我想返回单个字段的值,这是一个 int 值。
int thivalue = (from q in context.tablename
where q.ID == id
orderby q.fieldname descending
select q).FirstOrDefault().fieldname;
问题是查询可能不返回任何结果,在这种情况下我希望这个值为 0。
当然,如果没有结果,我会在尝试访问不存在的字段时遇到异常。所以看来我的选择是a)返回行(我不需要),所以我可以测试null并从那里开始,或者b)在它周围包装一个try catch并将值设置为0,这似乎有点笨重。
我想也许 DefaultIfEmpty() 会帮助我,但如果我想要的只是一个单一的值,这似乎不是。
那么这样做的正确方法是什么?当我只需要一个值时,我是否只是固执地不想返回整行?
附录:(如果有人感兴趣)
在他的回答中,伯克利布罗斯给了我两个明显相同的选择。但只有第二个给了我正确的结果。OrderByDescending 似乎有些不对劲。使用 Glimpse 我查看了每个查询。
var nextSequence = db.PaneContents
.Where(q=>q.QuizPaneID == quizPaneId)
.OrderByDescending(q=>q.Sequence)
.Select (q=>q.Sequence)
.DefaultIfEmpty()
.First();
产生了这个查询:
SELECT
CASE WHEN ([Limit1].[C1] IS NULL) THEN 0 ELSE [Limit1].[Sequence] END AS [C1]
FROM ( SELECT TOP (1)
[Project1].[Sequence] AS [Sequence],
[Project1].[C1] AS [C1]
FROM ( SELECT 1 AS X ) AS [SingleRowTable1]
LEFT OUTER JOIN (SELECT
[Extent1].[Sequence] AS [Sequence],
cast(1 as tinyint) AS [C1]
FROM [dbo].[PaneContents] AS [Extent1]
WHERE [Extent1].[QuizPaneID] = 274 /* @p__linq__0 */ ) AS [Project1] ON 1 = 1
) AS [Limit1]
然而
var nextSequence = (from q in db.PaneContents
where q.QuizPaneID == quizPaneId
orderby q.Sequence descending
select q.Sequence).FirstOrDefault();
产生了这个查询:
SELECT TOP (1)
[Project1].[Sequence] AS [Sequence]
FROM ( SELECT
[Extent1].[Sequence] AS [Sequence]
FROM [dbo].[PaneContents] AS [Extent1]
WHERE [Extent1].[QuizPaneID] = 274 /* @p__linq__0 */
) AS [Project1]
ORDER BY [Project1].[Sequence] DESC
看起来在第一个示例中 OrderByDescending() 不知何故在翻译中丢失了?无论如何,出于我的目的,不需要 DefaultIfEmpty(),第二个示例更简单。我只是觉得它不起作用很奇怪(“不起作用”是指它选择了错误的值,因为它没有按降序排序),因为它看起来应该如此。