所以基本上我必须为4个不同的角色获得4个不同的员工列表。 List of Roles
是List of Enum
,如下所示:
public enum Roles {
[Description("Level 1")]
L1,
[Description("Level 2")]
L2,
[Description("Level 3")]
L3,
[Description("Level 4")]
L4
};
L1
可以查看L1
,L2
,L3
和L4
L2
可以查看L2
,L3
和L4
L3
可以查看L3
和L4
。L4
无权查看任何员工。现在,下面是我如何编写查询以获取员工。
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;
}
}
所以在上面的代码中我有相同的LINQ查询,但只有where
条件不同。有没有什么方法可以准备动态where
条件并为所有人获取列表一次?
答案 0 :(得分:2)
这应该有效。它假设每个 GlobalMethods.Roles 都可以查看具有更大int值的所有角色。这就是你所说的规则的角色。
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();
}
答案 1 :(得分:1)
这是简化的,但您可以这样做:
class Program
{
static void Main(string[] args)
{
var list = new List<Person>
{
new Person{ Name = "John" },
new Person{ Name = "Amy" }
};
Func<Person, bool> pred = null;
Roles role = Roles.RoleA;
switch (role)
{
case Roles.RoleA:
pred = p => p.Name.StartsWith("J");
break;
case Roles.RoleB:
pred = p => p.Name.StartsWith("A") && p.Name.Length >= 3;
break;
default:
break;
}
var result = list.Where(pred);
}
}
class Person
{
public string Name { get; set; }
}
enum Roles
{
RoleA,
RoleB
}
答案 2 :(得分:1)
以下是通用的表达式树扩展方法,以满足以下要求(您当然需要修改以满足您的特定要求)
T
是IEnumerable
T1
是where子句中过滤的列类型
针对给定的ParameterExpression
外部扩展方法声明T
以便重用,同时编译Expression Tree to Func
,尽管这也可以在Extension method
中单独完成在Func
代
ParameterExpression parameterType = Expression.Parameter(typeof(T), "object");
public static class CustomExpression
{
// Create Initial Expression Tree
public static BinaryExpression InitialExpression<T,T1>(
ParameterExpression parameterType
string columnName,
T1 value)
{
// Optional can be taken outside the Extension method to create a Func<T,bool>
//ParameterExpression parameterType = Expression.Parameter(typeof(T), "object");
MemberExpression typeColumn = Expression.Property(parameterType, columnName);
ConstantExpression constant = Expression.Constant(value, typeof(T1));
return Expression.NotEqual(typeColumn, constant);
}
// Create Combined Expression Tree
public static BinaryExpression CombinedExpression<T,T1>(this BinaryExpression mainExpression,
ParameterExpression parameterType
string columnName,
T1 value)
{
// Optional can be taken outside the Extension method to create a Func<T,bool>
//ParameterExpression parameterType = Expression.Parameter(typeof(T), "object");
MemberExpression typeColumn = Expression.Property(parameterType, columnName);
ConstantExpression constant = Expression.Constant(value, typeof(T1));
return Expression.And(mainExpression,Expression.NotEqual(typeColumn, constant));
}
}
以下是您案例中的调用层次结构:
声明Linq
查询的最终二进制表达式:
BinaryExpression finalBinaryExpression = null;
switch (_role)
{
case GlobalMethods.Roles.L1:
finalBinaryExpression =
CustomExpression.InitialExpression<EmployeeViewModel,int>
(parameterType,"EmpID",homeViewModel.UserViewModel.EmpID);
break;
case GlobalMethods.Roles.L2:
finalBinaryExpression =
CustomExpression.InitialExpression<EmployeeViewModel,int>
(parameterType,"EmpID",homeViewModel.UserViewModel.EmpID)
.CombinedExpression<EmployeeViewModel,Roles>
(parameterType,"EmpRole",Enum.GetName(typeof(GlobalMethods.Roles), 0));
break;
case GlobalMethods.Roles.L3:
finalBinaryExpression =
CustomExpression.InitialExpression<EmployeeViewModel,int>
(parameterType,"EmpID",homeViewModel.UserViewModel.EmpID)
.CombinedExpression<EmployeeViewModel,Roles>
(parameterType,"EmpRole",Enum.GetName(typeof(GlobalMethods.Roles), 0))
.CombinedExpression<EmployeeViewModel,Roles>
(parameterType,"EmpRole",Enum.GetName(typeof(GlobalMethods.Roles), 1));
break;
}
通过编译二进制表达式创建genericFunc
,如下所示
Func<T, bool> filterFunc = Expression.Lambda<Func<T, bool>>
(finalBinaryExpression, parameterType).Compile();
最终结果应用上面创建的Func
var finalResult = context.tblEmployees.Where(o => filterFunc(o));