C# 如何向 linq 查询添加动态“where”子句?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/180405/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you add dynamic 'where' clauses to a linq query?
提问by Nick
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.
我有一个带有位掩码的 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;
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
关于如何动态构建我的查询的任何指示?谢谢
采纳答案by ilitirit
You can use the PredicateBuilderclass.
您可以使用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 to SQL 和实体框架高级用户的免费扩展集。
回答by Dylan Beattie
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 语法可以代替循环,但概念应该是相同的。
回答by Carlton Jenke
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;
}
回答by alexmac
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/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
Expression Trees & Lamda expressions: http://msdn.microsoft.com/en-us/library/bb882637.aspx
表达式树和 Lamda 表达式:http: //msdn.microsoft.com/en-us/library/bb882637.aspx
回答by Michael Damatov
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 参数作为位掩码,而不是数组。
回答by Lucas
Here's one way of adding a variable number of whereclauses to your LINQ query. Note that I haven't touched your bitmask logic, I just focused on the multiple wheres.
这是向 LINQ 查询添加可变数量的where子句的一种方法。请注意,我没有触及您的位掩码逻辑,我只是关注了多个wheres。
// 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 ANDthe whereclauses and you wanted to ORthem. The following approach (a inner join) works in LINQ to Objects but can not be translated to SQL with LINQ to SQL:
编辑:其实,这种意志和在那里条款和你想或他们。以下方法(内部联接)适用于 LINQ to Objects,但无法使用 LINQ to SQL 转换为 SQL:
var result = from user in Users
from role in UserRoles
where (user.UserRolesBitmask & role) == role
select user;