我有一个User表,它有一个包含用户角色的位掩码。下面的linq查询返回其角色包括1、4或16的所有用户。
var users = from u in dc.Users
where ((u.UserRolesBitmask & 1) == 1)
|| ((u.UserRolesBitmask & 4) == 4)
|| ((u.UserRolesBitmask & 16) == 16)
select u;
我想把它重写到下面的方法中,从给定的角色返回所有用户,这样我就可以重用它:
private List<User> GetUsersFromRoles(uint[] UserRoles) {}
关于如何动态构建我的查询,有什么建议吗?感谢
您可以使用PredicateBuilder类。
PredicateBuilder已在LINQKit NuGet包中发布
LINQKit是为LINQ to SQL和实体框架高级用户提供的一组免费扩展。
假设您的UserRoles值本身就是位掩码,这样的方法会起作用吗?
private List<User> GetUsersFromRoles(uint[] UserRoles) {
uint roleMask = 0;
for (var i = 0; i < UserRoles.Length;i++) roleMask= roleMask| UserRoles[i];
// roleMasknow contains the OR'ed bitfields of the roles we're looking for
return (from u in dc.Users where (u.UserRolesBitmask & roleMask) > 0) select u);
}
可能有一种很好的LINQ语法可以代替循环,但概念应该是一样的。
有几种方法可以做到这一点:
LINQ动态查询库:http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
表达式树&Lamda表达式:http://msdn.microsoft.com/en-us/library/bb882637.aspx
以下是一种将可变数量的where子句添加到LINQ查询中的方法。请注意,我还没有触及您的比特掩码逻辑,我只是关注中的倍数。
// C#
private List<User> GetUsersFromRoles(uint[] UserRoles)
{
var users = dc.Users;
foreach (uint role in UserRoles)
{
users = users.Where(u => (u.UserRolesBitmask & role) == role);
}
return users.ToList();
}
编辑:实际上,这将ANDwhere子句,并且您希望OR它们。以下方法(内部联接)适用于LINQ to Objects,但不能使用LINQ to SQL转换为SQL:
var result = from user in Users
from role in UserRoles
where (user.UserRolesBitmask & role) == role
select user;
怎么样?它不是动态linq,而是实现了目标。
private List<User> GetUsersFromRoles(uint[] userRoles)
{
List<User> users = new List<User>();
foreach(uint userRole in UserRoles)
{
List<User> usersInRole = GetUsersFromRole(userRole);
foreach(User user in usersInRole )
{
users.Add(user);
}
}
return users;
}
private List<User> GetUsersFromRole(uint userRole)
{
var users = from u in dc.Users
where ((u.UserRolesBitmask & UserRole) == UserRole)
select u;
return users;
}
private List<User> GetUsersFromRoles(uint UserRoles) {
return from u in dc.Users
where (u.UserRolesBitmask & UserRoles) != 0
select u;
}
但是,UserRoles参数应该作为位掩码而不是数组提供。