如何在linq查询中添加动态“where”子句?

时间:2008-10-07 21:03:50

标签: c# linq dynamic

我有一个带有位掩码的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) {}

关于如何动态构建查询的任何指针?感谢

6 个答案:

答案 0 :(得分:32)

您可以使用PredicateBuilder类。

PredicateBuilder已在LINQKit NuGet package

中发布
  

LINQKit是LINQ to SQL和Entity Framework高级用户的一组免费扩展。

答案 1 :(得分:3)

假设您的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语法可以代替循环,但概念应该是相同的。

答案 2 :(得分:3)

答案 3 :(得分:3)

这是向LINQ查询添加可变数量的 where 子句的一种方法。 请注意,我没有碰过你的位掩码逻辑,我只专注于多个 where s。

// 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();
}

编辑:实际上,这将 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;

答案 4 :(得分:1)

这是怎么回事?它不是动态的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;    
}

答案 5 :(得分:0)

private List<User> GetUsersFromRoles(uint UserRoles) {
  return from u in dc.Users            
         where (u.UserRolesBitmask & UserRoles) != 0
         select u;
}

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