Joe*_*oel 3 entity-framework-4 dbcontext asp.net-mvc-4
这类事总是让我烦恼,所以我想我会从聪明的人那里寻找一种"更好的方式".
我有一个查询,我想返回单个字段的值,这是一个int值.
int thivalue = (from q in context.tablename
where q.ID == id
orderby q.fieldname descending
select q).FirstOrDefault().fieldname;
Run Code Online (Sandbox Code Playgroud)
问题是查询可能没有返回结果,在这种情况下我希望thisvalue为0.
当然,如果没有结果,我会尝试访问不存在的字段.所以我的选择似乎是a)返回行(我不需要),所以我可以测试null并从那里开始,或者b)在它周围包装一个try catch并将值设置为0,其中看起来有点笨重.
我想也许DefaultIfEmpty()会帮助我,但似乎不是我想要的只是单个值.
那么这样做的正确方法是什么?当我只需要一个单独的值时,我只是顽固地想要不返回整行吗?
附录:(如果有人有兴趣)
在他的回答中,berkeleybross给了我两个明显相同的选择.但只有第二个给了我正确的结果.OrderByDescending似乎有些不对劲.使用Glimpse我查看了每个查询.
var nextSequence = db.PaneContents
.Where(q=>q.QuizPaneID == quizPaneId)
.OrderByDescending(q=>q.Sequence)
.Select (q=>q.Sequence)
.DefaultIfEmpty()
.First();
Run Code Online (Sandbox Code Playgroud)
产生了这个查询:
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]
Run Code Online (Sandbox Code Playgroud)
而
var nextSequence = (from q in db.PaneContents
where q.QuizPaneID == quizPaneId
orderby q.Sequence descending
select q.Sequence).FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)
产生了这个查询:
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
Run Code Online (Sandbox Code Playgroud)
看起来在第一个例子中,OrderByDescending()以某种方式在翻译中丢失了?无论如何,出于我的目的,不需要DefaultIfEmpty(),第二个例子更简单.我只是觉得奇怪的是它不起作用('不起作用'我的意思是它选择了错误的值,因为它没有排序降序)因为它看起来应该如此.
如果我理解正确,你可以试试这个:
int thisvalue = context.tablename
.Where(q => q.ID == id)
.OrderByDescending(q => q.fieldname)
.Select(q => q.fieldname)
.FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)
要么
int thisvalue = (from q in context.tablename
where q.ID == id
orderby q.fieldname descending
select q.fieldname).FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)
在调用FirstOrDefault()之前选择q.fieldname将使SQL返回第一个item字段名(而不是整个第一行).
另外,q.ID是唯一的吗?如果是这样,那么您不需要按fieldname排序,并且可以使用SingleOrDefault而不是FirstOrDefault.Single确保只有一个元素,而First确保至少有一个元素.Single应该用于表示您的假设,它对于更多自我记录代码是唯一的.
int thisvalue = context.tablename
.Where(q => q.ID == id)
.Select(q => q.fieldname)
.SingleOrDefault();
Run Code Online (Sandbox Code Playgroud)