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 および Entity Framework パワー ユーザー向けの無料の拡張機能セットです。

于 2008-10-07T21:18:04.440 に答える
3

LINQ クエリに可変数のwhere句を追加する 1 つの方法を次に示します。ビットマスク ロジックには触れていないことに注意してください。複数の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 句の AND になり、それら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 に答える
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

式ツリーとラムダ式: http://msdn.microsoft.com/en-us/library/bb882637.aspx

于 2008-10-07T21:14:54.290 に答える
1

どうですか?動的リンクではありませんが、目標を達成します。

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 に答える