Pregunta

Tengo una tabla de usuario con una máscara de bits que contiene los roles del usuario. La siguiente consulta de linq devuelve todos los usuarios cuyos roles 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 que aparece a continuación para que todos los usuarios de los roles dados vuelvan a usarlo:

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

¿Algún indicador sobre cómo construir dinámicamente mi consulta? Gracias

¿Fue útil?

Solución

Puede usar la clase PredicateBuilder .

PredicateBuilder se ha lanzado en el paquete LINQKit NuGet

  

LINQKit es un conjunto gratuito de extensiones para los usuarios avanzados de LINQ to SQL y Entity Framework.

Otros consejos

Asumiendo que los valores de UserRoles son máscaras de bits, ¿funcionaría algo como esto?

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 de LINQ que funcione en lugar de los bucles, pero el concepto debería ser el mismo.

Hay varias formas de hacerlo:

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

Árboles de expresión & amp; Expresiones de Lamda: http://msdn.microsoft.com/en-us/library/bb882637. aspx

Esta es 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 máscara de bits, simplemente me centré en los múltiples 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();
}

EDITAR: En realidad, esto será Y las cláusulas where y usted quiso O . El siguiente enfoque (una unión interna) funciona en LINQ to Objects, pero no se puede traducir a SQL con LINQ to SQL:

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

¿Qué tal esto? No es un linq 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;    
}
private List<User> GetUsersFromRoles(uint UserRoles) {
  return from u in dc.Users            
         where (u.UserRolesBitmask & UserRoles) != 0
         select u;
}

El parámetro UserRoles debe proporcionarse, sin embargo, como una máscara de bits, en lugar de una matriz.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top