Guruprasad Rao Guruprasad Rao - 1 month ago 10
C# Question

Creating where condition for LINQ within switch statement

So basically I have to get 4 different List of employees for 4 different roles.

List of Roles
is a
List of Enum
as below:

public enum Roles {
[Description("Level 1")]
L1,

[Description("Level 2")]
L2,

[Description("Level 3")]
L3,

[Description("Level 4")]
L4
};



  • L1
    can view
    L1
    ,
    L2
    ,
    L3
    and
    L4

  • L2
    can view
    L2
    ,
    L3
    and
    L4

  • L3
    can view
    L3
    and
    L4
    .

  • L4
    do not have permission to view any of employee.



Now below is how I have written query for fetching employees.

if (!Equals(Role, Enum.GetName(typeof(GlobalMethods.Roles), 3)))
{
var _role = (GlobalMethods.Roles)Enum.Parse(typeof(GlobalMethods.Roles), Role,true);
List<EmployeeViewModel> employees = new List<EmployeeViewModel>();
switch (_role)
{
case GlobalMethods.Roles.L1:
employees = context.tblEmployees.Where(x => x.EmpID != homeViewModel.UserViewModel.EmpID).ToList().Select(x => new EmployeeViewModel
{
EmpActive = x.EmpActive,
EmpDOB = x.EmpDOB,
EmpName = x.EmpName
}).ToList();
break;
case GlobalMethods.Roles.L2:
employees= context.tblEmployees.Where(x => x.EmpID != homeViewModel.UserViewModel.EmpID).ToList().Where(x=>x.EmpRole != Enum.GetName(typeof(GlobalMethods.Roles), 0)).Select(x => new EmployeeViewModel
{
EmpActive = x.EmpActive,
EmpDOB = x.EmpDOB,
EmpName = x.EmpName,
}).ToList();
break;
case GlobalMethods.Roles.L3:
employees = context.tblEmployees.Where(x => x.EmpID != homeViewModel.UserViewModel.EmpID).ToList().Where(x.EmpRole != Enum.GetName(typeof(GlobalMethods.Roles), 0) && x.EmpRole != Enum.GetName(typeof(GlobalMethods.Roles), 1)).Select(x => new EmployeeViewModel
{
EmpActive = x.EmpActive,
EmpDOB = x.EmpDOB,
EmpName = x.EmpName,
}).ToList();
break;
default: break;
}
}


So in the above code I have the same LINQ query but only the
where
condition differs. Is there any way I can prepare a dynamic
where
condition and fetch the list once for all?

Answer

This should work. It makes the assumption that each GlobalMethods.Roles can view all roles with a greater int values. That is the case for the roles are rules that you have stated.

if (!Equals(Role, Enum.GetName(typeof(GlobalMethods.Roles), 3)))
{
     var _role = (GlobalMethods.Roles)Enum.Parse(typeof(GlobalMethods.Roles), Role, true);
     List<EmployeeViewModel> employees = new List<EmployeeViewModel>();
     string[] viewableRoles = GetViewableRoles(_role);
     employees = context.tblEmployees
                .Where(x => x.EmpID != homeViewModel.UserViewModel.EmpID && viewableRoles.Contains(x.EmpRole))
                .Select(x => new EmployeeViewModel
                {
                    EmpActive = x.EmpActive,
                    EmpDOB = x.EmpDOB,
                    EmpName = x.EmpName
                }).ToList();
}

private string[] GetViewableRoles(GlobalMethods.Roles userRole)
{
    //Uncomment if L4 can actually view no roles, including itself.
    // /if (userRole == GlobalMethods.Roles.L4)
    // {
    //  return new string[0];
    // }

    IEnumerable<GlobalMethods.Roles> allRoles = Enum.GetValues(typeof(GlobalMethods.Roles)).Cast<GlobalMethods.Roles>();
    return (from role in allRoles 
                where (int)role >= (int)userRole 
                select role.ToString()).ToArray();
}