C# 如何将动态“where”子句添加到linq查询?

C# 如何将动态“where”子句添加到linq查询?,c#,linq,dynamic,C#,Linq,Dynamic,我有一个包含用户角色的位掩码的用户表。下面的linq查询返回角色包括1、4或16的所有用户 var users = from u in dc.Users where ((u.UserRolesBitmask & 1) == 1) || ((u.UserRolesBitmask & 4) == 4) || ((u.UserRolesBitmask & 16) == 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;
我想将其重写为下面的方法,以返回给定角色中的所有用户,以便可以重用它:

private List<User> GetUsersFromRoles(uint[] UserRoles) {}

有没有关于如何动态构建我的查询的指针?谢谢

假设您的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,而是实现了目标

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;    
}

有几种方法可以做到这一点:

LINQ动态查询库:

表达式树和Lamda表达式:

但是,UserRoles参数应作为位掩码而不是数组提供。

您可以使用该类

PredicateBuilder已在中发布

LINQKit是一组免费的扩展,用于LinqtoSQL和实体框架高级用户


这里有一种向LINQ查询中添加数量可变的where子句的方法。 请注意,我没有触及您的位掩码逻辑,我只关注多个where


这将返回匹配所有给定角色的用户。他的方法返回与任何给定角色匹配的用户。这应该有效。您没有使用动态where子句,而是将其简化为单个where子句。您提到的好的LINQ语法可能是:uint roleMask=UserRoles.Aggregate0,combined,role=>combined | role;此外,您需要在GetUsersFromRoleApparanty中列出PredicateBuilder类有两个版本:网站上的源代码示例©Albahari&O'Reilly,保留所有权利;作为LinqKit的一部分,LinqKit拥有许可免费许可证,这意味着您可以随意修改它,并将其合并到您自己的商业或非商业软件中。LinqKit可通过NuGet获得。
private List<User> GetUsersFromRoles(uint UserRoles) {
  return from u in dc.Users            
         where (u.UserRolesBitmask & UserRoles) != 0
         select u;
}
// 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();
}
var result = from user in Users
             from role in UserRoles
             where (user.UserRolesBitmask & role) == role
             select user;