2015-10-15 82 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))