2017-08-30 34 views
0

比方說,我有一個名爲vw_Project的EF類,其中包含屬性字符串ProjectTitle以及其他屬性。我想運行一個高效的LINQ查詢,它只查詢結果中第一條記錄的第一列(第一個「單元格」,類似於SqlCommand.ExecuteScalar)。我可能會寫這樣的事:實體框架 - 在查詢單個列時,如何區分沒有結果和NULL值的結果?

string projectTitle = context.vw_Projects 
    .Where(p => p.ProjectID == projID) 
    .Select(p => p.ProjectTitle) 
    .FirstOrDefault(); 

的問題是,我不能告訴我查詢是否有任何結果,或者如果它只是一個得到的結果與該varchar列的NULL值。

我總是可以查詢整個對象來做出決定,然後將ProjectTitle列提取到內存中的字符串變量中,但是我會查詢一堆我不需要的列,這是一個糟糕的解決方案。這看起來像這樣:

string projectTitle; 
vw_Project project = context.vw_Projects 
    .Where(p => p.ProjectID == projID) 
    .FirstOrDefault(); 

if (project != null) 
{ 
    projectTitle = project.ProjectTitle; 
} 
else 
{ 
    throw new Exception("Invalid Project ID"); 
} 

如何在不查詢其他列或行的情況下做出此決定?

+0

我不認爲底部的解決方案是「窮人」:除非您急切地在'Project'上加載集合,否則開銷將很難被檢測到。你應該結合'Where'和'FirstOrDefault',即'FirstOrDefault(p => p.ProjectID == projID)'。 – dasblinkenlight

+0

@dasblinkenlight'FirstOrDefault'的好建議 - 我會相應地更新我的答案。至於另一個建議從數據庫中獲取整個對象的解決方案,你是對的,在大多數情況下它不會產生巨大的影響。但是,如果它是一個大型表格,尤其是一個具有計算列的表格,或者如果您需要獲取多行而不是一個,那麼這是一個不應該被遺忘的重要優化。 –

回答

2

如果您僅使用所需屬性創建內嵌匿名類型,則仍然可以確定是否獲得零結果或獲得NULL記錄。

string projectTitle; 
var result = context.vw_Projects 
    .Where(p => p.ProjectID == projID) 
    .Select(p => new { p.ProjectTitle }) 
    .FirstOrDefault(); 

if (result != null) 
{ 
    projectTitle = result.ProjectTitle; 
} 
else 
{ 
    throw new Exception("Invalid Project ID"); 
} 

如果查詢得到的結果,該result實例將不能爲空,不管內部ProjectTitle屬性是否爲空。

+2

請注意'Take(1)'是多餘的。 'FirstOrDefault'做同樣的事情。 –

+0

@GertArnold你是對的。在我的回答和迴應中糾正了它。 –