多个CheckBox选择结果使用Linq而不进行硬编码

时间:2015-02-16 13:36:28

标签: c# asp.net-mvc linq asp.net-mvc-4 linq-to-entities

数据库说明(实际列和表名称不同)

EmployeeeID      IsSicked   IsRetired    IsHoliday  
1                false      false        true
2                true       false        true
3                true       true         true
4                false      false        false

我有什么问题?
我的应用程序中有一个IsSicked,IsRetired和IsHoliday的复选框,允许用户检查多个选择并提交。
系统将根据用户的选择从数据库返回员工列表。例如,当用户勾选IsSicked和IsRetired时,系统将返回生病并从数据库中退出的用户列表。

基于以下代码,我需要编写2 ^ 3 = 8种可能性来获得结果。 当列扩展为n列(排除employeeID列)时,我需要编写2 ^ n if else语句来获取查询。 如果有10列(10个复选框选择),那么我需要写2 ^ 10 = 1024 if else语句

在我看来,这应该是开发人员面临的一个常见问题,遗憾的是我无法在线找到一个好的解决方案

对解决方案的期望
C#代码和/或LINQ查询的通用组合,如果(...)其他if(...)

,则无需硬编码如下所示的逻辑
var employee = db.Employee.AsQueryable():
if(model.IsSicked == true)
{
    employee.Where(z => z.IsSicked == true)
}
else if(model.IsRetired == true)
{
    employee.Where(z => z.IsRetired == true)
}
...
...

else if(model.IsSicked == true && model.IsRetired == true)
{
    employee.Where(z => z.IsSick == true || z.IsRetired == true)
}
else if (model.IsSicked == true && model.IsRetired == true && model.IsHoliday == true)
{
    employee.Where(z => z.IsSick == true || z.IsRetired == true || z.IsHoliday == true)
}

3 个答案:

答案 0 :(得分:3)

为什么不在enum上使用[Flags]

[Flags]
public enum EmployeeStatus
{
    None = 0,
    Sick = 1,
    Retired = 2,
    Holiday = 4
}

在您的数据库中,您可以将其存储为整数。

您的模型与

类似
public class Employee
{
    public int Id { get; set; }
    public EmployeeStatus Status { get; set }
}

然后LINQ查询变得类似于:

employee.Where(z => z.Status == EmployeeStatus.Sick)

由于使用[Flags],您可以针对多种状态执行以下操作,例如生病和退休:

employee.Where(z => z.Status == (EmpoyeeStatus.Sick | EmployeeStatus.Retired))

请注意,|是布尔OR,其转换如下:

  EmpoyeeStatus.Sick | EmployeeStatus.Retired
= 1 | 2
= b01 | b10
= b11
= 3

如此有效地起作用"和"在我们的逻辑中。

答案 1 :(得分:0)

您可以使用名为LINQKit的库并使用其PredicateBuilder创建带动态OR的谓词。

var employee = db.Employee.AsQueryable():
var predicate = PredicateBuilder.False<Employee>();
if (model.IsSicked == true)
    predicate = predicate.Or(p => p.IsSick == model.IsSick);
if (model.IsRetired == true)
    predicate = predicate.Or(p => p.IsRetired == model.IsRetired);
if (model.IsHoliday == true)
    predicate = predicate.Or(p => p.IsHoliday == model.IsHoliday);
var result = employee.AsExpandable().Where(c => predicate.Invoke(c)).ToList()

答案 2 :(得分:0)

你可以建立你的Where谓词:

var employee = db.Employee.AsQueryable():

if(model.IsSicked == true)
    employee = employee.Where(z => z.IsSicked == true)

if(model.IsRetired == true)
    employee = employee.Where(z => z.IsRetired == true)

if (model.IsHoliday == true)
    employee = employee.Where(z => z.IsHoliday == true)

或者,你可以这样做:

employee.Where(z => (z.IsSicked || !model.IsSicked) &&
                    (z.IsRetired || !model.IsRetired) &&
                    (z.IsHoliday || !model.IsHoliday))
相关问题