2013-10-13 80 views
3

這種類型的事情總是給我帶來了困擾,所以我想我會從你聰明的人身上尋找一種「更好的方式」。當檢索單個字段值時,FirstOrDefault()

我有一個查詢,我想返回單個字段的值,這是一個int值。

int thivalue = (from q in context.tablename  
    where q.ID == id 
    orderby q.fieldname descending 
    select q).FirstOrDefault().fieldname; 

問題是查詢可能返回任何結果在這種情況下,我想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(); 

產生這個查詢:

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()不需要,第二個例子更直接。我只是覺得奇怪,它不起作用('沒有工作'我的意思是它選擇了錯誤的值,因爲它沒有排序降序),因爲它看起來應該是這樣。

int thisvalue = context.tablename 
         .Where(q => q.ID == id) 
         .OrderByDescending(q => q.fieldname) 
         .Select(q => q.fieldname) 
         .FirstOrDefault(); 

int thisvalue = (from q in context.tablename  
       where q.ID == id 
       orderby q.fieldname descending 
       select q.fieldname).FirstOrDefault(); 

選擇q.fieldname調用FirstOrDefault前:

回答

6

如果我理解正確的話,你可以試試這個()將使SQL返回第一項字段名(而不是整個第一行)。


另外,q.ID是否是唯一的?如果是這樣,那麼你不需要按字段名排序,你可以使用SingleOrDefault而不是FirstOrDefault。Single確保只有一個元素,而First確保至少有一個元素。應該使用單個來表示你的假設,它對於更多的自我記錄代碼是唯一的。

int thisvalue = context.tablename 
         .Where(q => q.ID == id) 
         .Select(q => q.fieldname) 
         .SingleOrDefault(); 
+0

這看起來很正確,奇怪的是OrderByDescending在這個實例中似乎沒有達到預期的效果。如果我沒有調試.First()我得到一個升序列表...仍在玩它。 – Joel

+0

要回答你最後的問題,q.ID不是唯一的。這些是詳細記錄,我正在檢索'fieldname'的最大值(用於訂購目的的序列號),然後我增加並分配到一條新記錄 – Joel

+0

您的第二個示例正是我所需要的。他們都看起來功能相當,不知道爲什麼第一個沒有工作。 – Joel

1

我會做這樣的事情

int thisvalue = context.tablename 
    .Where(q => q.ID == id) 
    .OrderByDescending(q => q.fieldname) 
    .ToList() 
    .DefaultIfEmpty(new myObject {fieldname = 0}) 
    .FirstOrDefault().fieldname; 
+0

感謝您的建議,我首先看到了berkeleybross的答案,這更接近我開始的。儘管我喜歡DefaultIfEmpty示例。 – Joel

相關問題