Question

J'ai une table utilisateur avec un masque de traitement contenant les rôles de l'utilisateur. La requête linq ci-dessous renvoie tous les utilisateurs dont les rôles incluent 1, 4 ou 16.

var users = from u in dc.Users
            where ((u.UserRolesBitmask & 1) == 1)
               || ((u.UserRolesBitmask & 4) == 4)
               || ((u.UserRolesBitmask & 16) == 16)
            select u;

J'aimerais réécrire ceci dans la méthode ci-dessous pour renvoyer tous les utilisateurs des rôles donnés afin que je puisse le réutiliser:

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

Des indications sur la manière de construire dynamiquement ma requête? Merci

Était-ce utile?

La solution

Vous pouvez utiliser la classe PredicateBuilder .

PredicateBuilder a été publié dans le package LINQKit NuGet

.
  

LINQKit est un ensemble gratuit d’extensions pour les utilisateurs expérimentés de LINQ to SQL et Entity Framework.

Autres conseils

En supposant que vos valeurs UserRoles soient elles-mêmes des masques de bits, cela pourrait-il fonctionner?

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

Il existe probablement une belle syntaxe LINQ qui fonctionnera à la place des boucles, mais le concept devrait être le même.

Vous pouvez le faire de plusieurs manières:

Bibliothèques de requêtes dynamiques LINQ: http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

Arbres d'expression & amp; Expressions Lamda: http://msdn.microsoft.com/en-us/library/bb882637. aspx

Voici un moyen d’ajouter un nombre variable de clauses à votre requête LINQ. Notez que je n’ai pas touché à votre logique de masque de bits, je me suis concentré sur les multiples .

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

EDIT: En fait, cela va ET les clauses et vous souhaitez les OU . L’approche suivante (une jointure interne) fonctionne dans LINQ to Objects mais ne peut pas être traduite en SQL avec LINQ to SQL:

var result = from user in Users
             from role in UserRoles
             where (user.UserRolesBitmask & role) == role
             select user;

Comment ça? Ce n'est pas dynamique linq, mais atteint l'objectif.

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

Le paramètre UserRoles doit cependant être fourni en tant que masque de bits, au lieu de tableau.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top