Linq Ternary在where子句中覆盖所有记录

时间:2017-10-27 21:44:21

标签: c# entity-framework linq

我有一个工作订单表,其布尔字段为IsActive(即可以停用工作程序)。在我的存储库中,您可以请求活动工作程序,非活动工作程序或所有工作程序。我创建了一个enum来封装这三个状态,因为我也会在其他表上使用相同的方法。

我目前的Linq查询如下:

ActiveInactiveEnum activeInactive = ActiveInactiveEnum.Active; // or .Inactive or .All
var workOrders = _db.WorkOrders
                   .Where(i => activeInactive == ActiveInactiveEnum.Active ? i.IsActive.Value : activeInactive == ActiveInactiveEnum.Inactive? !i.IsActive.Value : true)
                   .Select(i => new workOrderViewModel{
                       Id = i.Id,
                       Title = i.Title
                   });

这看似按预期工作,但我不确定where子句的最后三元部分中的true。 Resharper希望我"简化条件三元表达"如下:

.Where(i => activeInactive == ActiveInactiveEnum.Active ? i.IsActive.Value : activeInactive != ActiveInactiveEnum.Inactive || !i.IsActive.Value)

但是当枚举值为.All时,这并不会返回所有记录。

是否有更简单或更好的方式来表示我的查询,尤其是Resharper会喜欢的方式?在where子句中使用true是否正确?

提前致谢

2 个答案:

答案 0 :(得分:2)

老实说,我会发现解决方案(在Resharper建议之前和之后)难以阅读和维护,比这样:

var query = _db.WorkOrders.AsQueryable();
if(activeInactive != ActiveInactiveEnum.All)
     query = query.Where(i => i.IsActive.Value == (activeInactive == ActiveInactiveenum.Active));
var workOrders = query.Select(i => new workOrderViewModel{
                       Id = i.Id,
                       Title = i.Title
                   });

答案 1 :(得分:1)

true时,您的代码和resharper代码都将返回activeInactive == ActiveInactiveEnum.All,但您声明:

  

但是,当枚举值为.All时,[ReSharper代码]不会返回所有记录。

然而,看看逻辑,它似乎必须如此。我们从:

开始
activeInactive == ActiveInactiveEnum.Active 
    ? i.IsActive.Value 
    : activeInactive != ActiveInactiveEnum.Inactive || !i.IsActive.Value

因此,当activeInactive == ActiveInactiveEnum.All时,条件评估为false,我们最终只查看第二个返回值:

activeInactive != ActiveInactiveEnum.Inactive || !i.IsActive.Value

我们有(true || <some value>),就像您的逻辑一样,它会返回true