25

我有一个包含用户角色的位掩码的用户表。下面的 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) {}

关于如何动态构建我的查询的任何指示?谢谢

4

6 回答 6

32

您可以使用PredicateBuilder类。

PredicateBuilder 已在LINQKit NuGet 包中发布

LINQKit 是一套免费的 LINQ to SQL 和实体框架高级用户扩展。

于 2008-10-07T21:18:04.440 回答
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 语法可以代替循环,但概念应该是相同的。

于 2008-10-07T21:11:04.797 回答
3

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

LINQ 动态查询库: http ://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

表达式树和 Lamda 表达式:http: //msdn.microsoft.com/en-us/library/bb882637.aspx

于 2008-10-07T21:14:54.290 回答
3

这是将可变数量的where子句添加到 LINQ 查询的一种方法。请注意,我没有触及您的位掩码逻辑,我只关注多个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();
}

编辑:实际上,这将与where子句和您想要对它们进行OR。以下方法(内部联接)适用于 LINQ to Objects,但不能使用 LINQ to SQL 转换为 SQL:

var result = from user in Users
             from role in UserRoles
             where (user.UserRolesBitmask & role) == role
             select user;
于 2008-10-07T21:21:22.250 回答
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;    
}
于 2008-10-07T21:14:33.790 回答
0
private List<User> GetUsersFromRoles(uint UserRoles) {
  return from u in dc.Users            
         where (u.UserRolesBitmask & UserRoles) != 0
         select u;
}

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

于 2008-10-07T21:15:11.480 回答