I've got a User table with a bitmask that contains the user's roles. The linq query below returns all the users whose roles include 1, 4 or 16.
我有一个包含用户角色的位掩码的用户表。下面的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;
I'd like to rewrite this into the method below to returns all the users from the given roles so I can reuse it:
我想把它重写为下面的方法,返回给定角色的所有用户,以便重用:
private List<User> GetUsersFromRoles(uint[] UserRoles) {}
Any pointers on how to dynamically build my query? Thanks
有关于如何动态构建查询的指针吗?谢谢
6 个解决方案
#1
31
You can use the PredicateBuilder class.
您可以使用PredicateBuilder类。
PredicateBuilder has been released in the LINQKit NuGet package
PredicateBuilder已经在LINQKit NuGet包中发布
LINQKit is a free set of extensions for LINQ to SQL and Entity Framework power users.
LINQKit是LINQ对SQL和实体框架高级用户的一组免费扩展。
#2
3
Assuming your UserRoles values are themselves bitmasks, would something like this work?
假设您的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);
}
There's probably a nice LINQ syntax that'll work in place of the loops, but the concept should be the same.
可能有一个不错的LINQ语法可以代替循环,但是概念应该是相同的。
#3
3
There are a couple of ways you can do this:
有几种方法可以做到这一点:
LINQ Dynamic query libraries: http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
LINQ动态查询库:http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamiclinq -part-1-using-the- LINQ Dynamic - querylibrary .aspx
Expression Trees & Lamda expressions: http://msdn.microsoft.com/en-us/library/bb882637.aspx
表达式树和Lamda表达式:http://msdn.microsoft.com/en-us/library/bb882637.aspx
#4
3
Here's one way of adding a variable number of where clauses to your LINQ query. Note that I haven't touched your bitmask logic, I just focused on the multiple wheres.
这里有一种向LINQ查询添加where子句数量可变的方法。注意,我没有触及你的位掩码逻辑,我只关注了多个位置。
// 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();
}
EDIT: Actually, this will AND the where clauses and you wanted to OR them. The following approach (a inner join) works in LINQ to Objects but can not be translated to SQL with LINQ to SQL:
编辑:实际上,这将和where子句,你想要或它们。下面的方法(内部连接)可以在LINQ中工作到对象,但是不能用LINQ转换到SQL:
var result = from u in Users
from role in UserRoles
where (u.UserRolesBitmask & role) == role)
select u;
#5
1
How's this? It is not dynamic linq, but accomplishes the goal.
这是如何?它不是动态的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;
}
#6
0
private List<User> GetUsersFromRoles(uint UserRoles) {
return from u in dc.Users
where (u.UserRolesBitmask & UserRoles) != 0
select u;
}
UserRoles parameter should be provided, however, as a bit mask, instead of array.
不过,应该提供UserRoles参数作为位掩码,而不是数组。
#1
31
You can use the PredicateBuilder class.
您可以使用PredicateBuilder类。
PredicateBuilder has been released in the LINQKit NuGet package
PredicateBuilder已经在LINQKit NuGet包中发布
LINQKit is a free set of extensions for LINQ to SQL and Entity Framework power users.
LINQKit是LINQ对SQL和实体框架高级用户的一组免费扩展。
#2
3
Assuming your UserRoles values are themselves bitmasks, would something like this work?
假设您的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);
}
There's probably a nice LINQ syntax that'll work in place of the loops, but the concept should be the same.
可能有一个不错的LINQ语法可以代替循环,但是概念应该是相同的。
#3
3
There are a couple of ways you can do this:
有几种方法可以做到这一点:
LINQ Dynamic query libraries: http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
LINQ动态查询库:http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamiclinq -part-1-using-the- LINQ Dynamic - querylibrary .aspx
Expression Trees & Lamda expressions: http://msdn.microsoft.com/en-us/library/bb882637.aspx
表达式树和Lamda表达式:http://msdn.microsoft.com/en-us/library/bb882637.aspx
#4
3
Here's one way of adding a variable number of where clauses to your LINQ query. Note that I haven't touched your bitmask logic, I just focused on the multiple wheres.
这里有一种向LINQ查询添加where子句数量可变的方法。注意,我没有触及你的位掩码逻辑,我只关注了多个位置。
// 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();
}
EDIT: Actually, this will AND the where clauses and you wanted to OR them. The following approach (a inner join) works in LINQ to Objects but can not be translated to SQL with LINQ to SQL:
编辑:实际上,这将和where子句,你想要或它们。下面的方法(内部连接)可以在LINQ中工作到对象,但是不能用LINQ转换到SQL:
var result = from u in Users
from role in UserRoles
where (u.UserRolesBitmask & role) == role)
select u;
#5
1
How's this? It is not dynamic linq, but accomplishes the goal.
这是如何?它不是动态的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;
}
#6
0
private List<User> GetUsersFromRoles(uint UserRoles) {
return from u in dc.Users
where (u.UserRolesBitmask & UserRoles) != 0
select u;
}
UserRoles parameter should be provided, however, as a bit mask, instead of array.
不过,应该提供UserRoles参数作为位掩码,而不是数组。