如何在linq查询中添加动态“where”子句?
我有一个带有位掩码的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 GetUsersFromRoles(uint[] UserRoles) {}
关于如何动态构建我的查询的任何指针? 谢谢
您可以使用PredicateBuilder类。
PredicateBuilder已经在LINQKit NuGet包中发布
LINQKit是LINQ to SQL和Entity Framework高级用户的一组免费扩展。
假设您的UserRoles值本身就是位掩码,那么这样的工作会起作用吗?
private List 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
Expression Trees&Lamda表达式: http : //msdn.microsoft.com/en-us/library/bb882637.aspx
这是向LINQ查询添加可变数量的where子句的一种方法。 请注意,我没有触及您的位掩码逻辑,我只关注多个位置 s。
// C# private List GetUsersFromRoles(uint[] UserRoles) { var users = dc.Users; foreach (uint role in UserRoles) { users = users.Where(u => (u.UserRolesBitmask & role) == role); } return users.ToList(); }
编辑:实际上,这将AND和where子句,你想要或他们。 以下方法(内部联接)在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 GetUsersFromRoles(uint[] userRoles) { List users = new List (); foreach(uint userRole in UserRoles) { List usersInRole = GetUsersFromRole(userRole); foreach(User user in usersInRole ) { users.Add(user); } } return users; } private List GetUsersFromRole(uint userRole) { var users = from u in dc.Users where ((u.UserRolesBitmask & UserRole) == UserRole) select u; return users; }
private List GetUsersFromRoles(uint UserRoles) { return from u in dc.Users where (u.UserRolesBitmask & UserRoles) != 0 select u; }
但是,应提供UserRoles参数作为位掩码,而不是数组。