この種のことはいつも私を悩ませてきたので、賢い人たちから「より良い方法」を探すことにしました.
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() が私を助けるかもしれないと思ったが、私が望むのは単一の値だけで終わることではないようだ。
それで、これを行う適切な方法は何ですか?行から単一の値だけが必要な場合に、行全体を返したくないという頑固なところがありますか?
追記:(興味のある方はどうぞ)
彼の回答で、berkeleybross は明らかに同等の 2 つの選択肢を与えてくれました。しかし、2番目のものだけが正しい結果をもたらしました。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() は必要ありませんでした.2番目の例はより簡単です. うまくいかなかったのは奇妙だと思いました(「うまくいかなかった」とは、降順でソートしなかったために間違った値を選択したことを意味します)。