基于不同bool条件的Linq where子句C#

xpcnnkqh  于 2022-12-06  发布在  C#
关注(0)|答案(4)|浏览(177)

嗨,我正在尝试基于多个布尔参数筛选项目列表。我有3个布尔参数(它们是UI中的3个复选框):IsTypeAIsTypeBIsTypeC。基于这3个值,我必须在项目的枚举属性(简称为“Type”)上过滤我的列表。可以选中多个复选框。在类型过滤器之上还有另一个过滤器(“in”,“out”),但那是有效的。到目前为止,我尝试的是:

FilteredDashboardItems = AllItems?.Where(x => 
                    Destination == "in" ?
                    (
                        (IsTypeA == true ? x.Type == Helpers.Enum.A : true)                    
                        &&
                        (IsTypeB == true ? x.Type == Helpers.Enum.B : true)                    
                        &&
                        (IsTypeC == true ? x.Type == Helpers.Enum.C : true)                    
                    ) : 
                    Destination == "out" ?
                    (
                        (IsTypeA == true ? x.Type == Helpers.Enum.A : true)                    
                        &&
                        (IsTypeB == true ? x.Type == Helpers.Enum.B : true)                    
                        &&
                        (IsTypeC == true ? x.Type == Helpers.Enum.C : true)                    
                    ) : true)?.ToList();

问题是:如果我选中了一个复选框(比如说IsTypeA),列表会被正确地过滤为A类型的项。但是如果我选中了另一个复选框(比如说IsTypeB),而不是显示A + B类型的过滤列表,列表返回0项。我该如何解决这个问题?

bxjv4tth

bxjv4tth1#

您正在使用&& And,这将为您提供两个筛选器的交集,因此为0条记录。
您需要使用OR||以便显示满足任一过滤器的元素。

k0pti3hp

k0pti3hp2#

您需要这样的东西:

List<int> typesToCheck = new List<int>();

    if (IsTypeA) typesToCheck.Add((int)Helpers.A);
    if (IsTypeB) typesToCheck.Add((int)Helpers.B);
    if (IsTypeC) typesToCheck.Add((int)Helpers.C);

    FilteredDashboardItems = AllItems?.Where(x => Destination == "in" ?
        (IsTypeA || IsTypeB || IsTypeC ? typesToCheck.Contains(x.Type) : true)
        :
        Destination == "out" ?
            (IsTypeA || IsTypeB || IsTypeC ? typesToCheck.Contains(x.Type) : true)
            : 
            true)?.ToList();

一旦你得到了这个形式,我相信你也可以简化目标条件

ercv8c1e

ercv8c1e3#

你的情况有点奇怪

IsTypeA == true ? x.Type == Helpers.Enum.A : true

如果IsTypeA不是可空bool,则不需要将其与true进行比较,因为逻辑上得到true == truefalse == true,因此可以只保留IsTypeA
我会改写你的条件:

FilteredDashboardItems = AllItems?.Where(x => 
                    Destination == "in" ?
                    (
                        (IsTypeA && x.Type == Helpers.Enum.A)                    
                        ||
                        (IsTypeB && x.Type == Helpers.Enum.B)                    
                        ||
                        (IsTypeC && x.Type == Helpers.Enum.C)                    
                    ) : 
                    Destination == "out" ?
                    (
                        (IsTypeA && x.Type == Helpers.Enum.A)                    
                        ||
                        (IsTypeB && x.Type == Helpers.Enum.B)                    
                        ||
                        (IsTypeC && x.Type == Helpers.Enum.C)                    
                    ) : true)?.ToList();

现在我们有了简单的逻辑:如果至少有一个选定类型与对象类型相同,则保留此对象

r8uurelv

r8uurelv4#

在这种类型的问题中,如果列表中有很多项,我建议将Linq写为QUERY,而不是写为Method。

(from item in AllItems
let firstCondition =  (IsTypeA && x.Type == Helpers.Enum.A) 
let secCondition =  (IsTypeB && x.Type == Helpers.Enum.B)
where firstCondition && secCondition
select item)?.ToList();

当你在表单中编写时,你在字母部分创建了临时变量,保存了时间,更重要是,我相信表单在复杂的逻辑中更具可读性。

相关问题