c# - query - ¿Cómo se agregan las cláusulas dinámicas ''where'' a una consulta linq?
query dynamic object c# (6)
¿Cómo es esto? No es dinámico, pero cumple el objetivo.
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;
}
Tengo una tabla de Usuario con una máscara de bits que contiene las funciones del usuario. La siguiente consulta de linq devuelve todos los usuarios cuyas funciones incluyen 1, 4 o 16.
var users = from u in dc.Users
where ((u.UserRolesBitmask & 1) == 1)
|| ((u.UserRolesBitmask & 4) == 4)
|| ((u.UserRolesBitmask & 16) == 16)
select u;
Me gustaría volver a escribir esto en el método a continuación para devolver todos los usuarios de los roles dados para poder reutilizarlo:
private List<User> GetUsersFromRoles(uint[] UserRoles) {}
¿Alguna sugerencia sobre cómo construir dinámicamente mi consulta? Gracias
Aquí hay una forma de agregar un número variable de cláusulas where a su consulta LINQ. Tenga en cuenta que no he tocado su lógica de bitmask, solo me centré en el múltiple donde 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();
}
EDITAR: En realidad, esto será Y las cláusulas WHERE y usted quería O ellos. El siguiente enfoque (una combinación interna) funciona en LINQ to Objects pero no se puede traducir a SQL con LINQ to SQL:
var result = from u in Users
from role in UserRoles
where (u.UserRolesBitmask & role) == role)
select u;
Hay un par de formas en que puede hacer esto:
Bibliotecas de consultas dinámicas LINQ: http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
Expresión de árboles y expresiones de Lamda: http://msdn.microsoft.com/en-us/library/bb882637.aspx
Puede usar la clase PredicateBuilder .
PredicateBuilder ha sido lanzado en el paquete LINQKit NuGet
LINQKit es un conjunto gratuito de extensiones para los usuarios avanzados de LINQ to SQL y Entity Framework.
Suponiendo que los valores de UserRoles son máscaras de bits, ¿funcionaría algo así?
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);
}
Probablemente haya una buena sintaxis LINQ que funcionará en lugar de los bucles, pero el concepto debería ser el mismo.
private List<User> GetUsersFromRoles(uint UserRoles) {
return from u in dc.Users
where (u.UserRolesBitmask & UserRoles) != 0
select u;
}
El parámetro UserRoles se debe proporcionar, sin embargo, como una máscara de bits, en lugar de una matriz.