2015-10-15 42 views
2

我想根據某些條件篩選對象列表。我見過一些在LINQ查詢中使用三元運算符的文章來完成這個任務。LINQ查詢中的三元運算符不像預期的那樣工作

該代碼片段的底部是我的LINQ查詢。我期望它測試每個where,而不是它似乎只嘗試第一個where,而剩下的。 List不包含我期望的數據。我究竟做錯了什麼?

private ObservableCollection<LogEvent> m_LogEvents = ApplicationData.MainLogEntries.LogEvents; 
    public ObservableCollection<LogEvent> LogEvents 
    { 
     get { return m_LogEvents; } 
     set { m_LogEvents = value; RaisePropertyChanged("LogEvents"); } 
    } 

    private bool m_ViewDebugLogs = false; 
    public bool ViewDebugLogs 
    { 
     get { return m_ViewDebugLogs; } 
     set { m_ViewDebugLogs = value; RaisePropertyChanged("ViewDebugLogs"); FilterList(); } 
    } 

    private bool m_ViewErrorLogs = true; 
    public bool ViewErrorLogs 
    { 
     get { return m_ViewErrorLogs; } 
     set { m_ViewErrorLogs = value; RaisePropertyChanged("ViewErrorLogs"); FilterList(); } 
    } 

    private bool m_ViewInfoLogs = true; 
    public bool ViewInfoLogs 
    { 
     get { return m_ViewInfoLogs; } 
     set { m_ViewInfoLogs = value; RaisePropertyChanged("ViewInfoLogs"); FilterList(); } 
    } 

    private void FilterList() 
    { 
     List<LogEvent> selectedEvents = (from x in LogEvents 
             where (ViewDebugLogs) ? x.Level == "Debug" : false 
             where (ViewErrorLogs) ? x.Level == "Error" : false 
             where (ViewInfoLogs) ? x.Level == "Info" : false 
             select x).ToList(); 

    } 

編輯:這樣做的目的是,如果相應的布爾ViewDebugLogsViewErrorLogs,或ViewInfoLogs,或三者的任意組合都啓用了日誌由相應的類型過濾。

我試着從沒有成功的答案如下:

這隻Debug Logs獲得:

  List<LogEvent> selectedEvents = (from x in LogEvents 
             where (ViewDebugLogs == true) ? x.Level == "Debug" : false 
             || (ViewErrorLogs == true) ? x.Level == "Error" : false 
             || (ViewInfoLogs == true) ? x.Level == "Info" : false 
             select x).ToList(); 

這隻會變得Debug Logs

  List<LogEvent> selectedEvents = (from x in LogEvents 
             where (ViewDebugLogs == true) ? x.Level == "Debug" : true 
             || (ViewErrorLogs == true) ? x.Level == "Error" : true 
             || (ViewInfoLogs == true) ? x.Level == "Info" : true 
             select x).ToList(); 

這得到什麼:

  List<LogEvent> selectedEvents = (from x in LogEvents 
             where (ViewDebugLogs == true) ? x.Level == "Debug" : true 
             where (ViewErrorLogs == true) ? x.Level == "Error" : true 
             where (ViewInfoLogs == true) ? x.Level == "Info" : true 
             select x).ToList(); 

回答

4

你可以使用

List<LogEvent> selectedEvents = (from x in LogEvents 
          where (ViewDebugLogs && x.Level == "Debug") 
           || (ViewErrorLogs && x.Level == "Error") 
           || (ViewInfoLogs && x.Level == "Info") 
          select x).ToList(); 

這是更清晰的(在我看來)。注意表達部分周圍的():我想確定AND和OR的評估順序。

+1

括號是什麼,結合使用'||'而不是多個'where's。謝謝! –

6

多個where條件被連接,就像您使用AND一樣。如果您嘗試使用OR,則應該使用||

List<LogEvent> selectedEvents = (from x in LogEvents 
           where (ViewDebugLogs) ? x.Level == "Debug" : false 
           || (ViewErrorLogs) ? x.Level == "Error" : false 
           || (ViewInfoLogs) ? x.Level == "Info" : false 
           select x).ToList(); 
+1

感謝您的回答!這很好地知道在多個「哪裏」。我早些時候嘗試過,查詢只返回調試日誌。如果我只是查詢'Where(ViewDebugLogs)? x.Level ==「Info」:false'沒有其他兩個whert(或三個列表中的任何一個)它返回預期的數據。剛剛嘗試過,以防我早早搞砸了,結果相同。 –

+1

嘗試並添加額外的括號(如'(((ViewDebugLogs)?x.Level ==「Debug」:false)' –

+0

括號做了它!我肯定沒有想到這些在必要的。謝謝! –

1

Where子句可以是where (ViewDebugLogs) ? x.Level == "Debug" : ((ViewErrorLogs) ? x.Level == "Error" : ((ViewInfoLogs) ? x.Level == "Info" : false))