J'ai une table utilisateur avec un masque de bits qui contient 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;
Je voudrais réécrire ceci dans la méthode ci-dessous pour retourner tous les utilisateurs des rôles donnés afin que je puisse le réutiliser:
private List<User> GetUsersFromRoles(uint[] UserRoles) {}
Des conseils sur la façon de créer dynamiquement ma requête? Merci
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 avancés de LINQ to SQL et Entity Framework.
Voici une façon d'ajouter un nombre variable de clauses where à votre requête LINQ. Notez que je n'ai pas touché à votre logique de masque de bits, je me suis concentré uniquement sur les multiples où 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();
}
EDIT: En fait, cela ET les où clauses et vous vouliez - OU eux. 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;
En supposant que vos valeurs UserRoles soient elles-mêmes des masques de bits, quelque chose comme ça fonctionnerait-il?
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 y a probablement une syntaxe Nice LINQ qui fonctionnera à la place des boucles, mais le concept devrait être le même.
Vous pouvez procéder 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 et expressions Lamda: http://msdn.Microsoft.com/en-us/library/bb882637.aspx
Comment c'est? Ce n'est pas linq dynamique, 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 sous la forme d'un masque de bits au lieu d'un tableau.