2013-05-03 45 views
1

我正在嘗試編寫一些邏輯來確定集合中某個對象的某個屬性的所有值是否都是數字並且大於零。我可以很容易地使用ForEach編寫這個,但是我想用Linq來做它。我試過這個:Linq to Objects - 爲任何非數字數據查詢對象

var result = entity.Reports.Any(
    x => 
    x.QuestionBlock == _question.QuestionBlock 
    && (!string.IsNullOrEmpty(x.Data)) && Int32.TryParse(x.Data, out tempVal) 
    && Int32.Parse(x.Data) > 0); 

它不能正常工作。我也試過,希望Int32上的TryParse()在第一次遇到不能被解析爲int的字符串時將返回false。但它看起來出來的參數將包含可以解析爲一個int的第一個值字符串值。

var result = entity.GranteeReportDataModels.Any(
    x => 
    x.QuestionBlock == _question.QuestionBlock 
    && (!string.IsNullOrEmpty(x.Data)) && Int32.TryParse(x.Data, out tempVal)); 

任何幫助,非常感謝!

+0

如果'TryParse'返回false,'out'參數的值是未定義的。 – Jodrell 2013-05-03 14:58:00

+0

如果'TryParse'返回'false',我相信out參數是0('int'的默認值),但這沒有記錄。實際上MSDN認爲它返回「未初始化」,但這是不可能的,因爲根據定義「out」意味着必須在函數返回之前設置一個值。反編譯該方法顯示,在實際完成任何工作之前,它實際上被設置爲0。 – 2013-05-03 15:02:10

+0

@BrianBall,我不會編寫依賴於該代碼的代碼,但它可能是正常的。 – Jodrell 2013-05-03 15:08:54

回答

3

如果要測試「所有」值是否滿足條件,則應使用擴展方法,而不是IEnumerable<T>而不是Any。我會寫這樣的:

var result = entity.Reports.All(x => 
{ 
    int result = 0; 
    return int.TryParse(x.Data, out result) && result > 0; 
}); 

我不相信你需要測試的空或空字符串,因爲如果你在一個空或空字符串傳遞int.TryPrase將返回false。

+0

+1更簡潔,但'result'初始化爲'0'是不必要的。 – Jodrell 2013-05-03 15:14:12

+0

這正是我正在尋找的。是的,如果邏輯逆轉,我的意思是所有雖然任何也可以使用。 – John 2013-05-03 16:01:53

0

你可以使用這個擴展,它試圖將字符串解析到int並返回int?

public static int? TryGetInt(this string item) 
{ 
    int i; 
    bool success = int.TryParse(item, out i); 
    return success ? (int?)i : (int?)null; 
} 

那麼這個查詢工作:

bool all = entity.Reports.All(x => { 
    if(x.QuestionBlock != _question.QuestionBlockint) 
     return false; 
    int? data = x.Data.TryGetInt(); 
    return data.HasValue && data.Value > 0; 
}); 

或更具可讀性(一點點效率較低):

bool all = entityReports 
    .All(x => x.Data.TryGetInt().HasValue && x.Data.TryGetInt() > 0 
      && x.QuestionBlock == _question.QuestionBlockint); 

該方法避免使用loc al變量爲out參數,這是Linq-To-Objects中未記錄的行爲,並可能在將來停止工作。它也更具可讀性。

+0

這種方法應該可以工作,並且具有代碼更加可重用的優點。但是我沒有嘗試過,因爲我沒有在這個特定的項目中使用擴展方法。但我會記住它。 – John 2013-05-03 16:05:00

1
var allDataIsNatural = entity.Reports.All(r => 
    { 
     int i; 
     if (!int.TryParse(r.Data, out i)) 
     { 
      return false; 
     } 

     return i > 0; 
    }); 

Any將返回時,第一行是true但是,你說清楚,你想檢查他們所有

+0

這個答案和Brian Balls一樣,但是Jodrell說它不像Brian的球那麼緊湊。非常感謝! – John 2013-05-03 16:03:10

相關問題