Cláusula donde dinámica (OR) en Linq to Entities

Resuelto Thomas Zweifel asked hace 11 años • 2 respuestas

En la publicación aquí , aprendí cómo crear una consulta dinámica utilizando la ejecución diferida de Linq. Pero la consulta en realidad utiliza una concatenación AND de la condición WHERE.

¿Cómo puedo lograr la misma consulta pero con una lógica OR?

Debido a la enumeración Flags, la consulta debe buscar Nombre de usuario , Nombre de usuario de Windows o ambos :

public User GetUser(IdentifierType type, string identifier)
{
    using (var context = contextFactory.Invoke())
    {
        var query = from u in context.Users select u;

        if (type.HasFlag(IdentifierType.Username))
            query = query.Where(u => u.Username == identifier);

        if (type.HasFlag(IdentifierType.Windows))
            query = query.Where(u => u.WindowsUsername == identifier);

        return query.FirstOrDefault();
    }
}
Thomas Zweifel avatar Jan 31 '13 15:01 Thomas Zweifel
Aceptado

Con PredicateBuilder de LINQKit puede crear predicados dinámicamente .

var query = from u in context.Users select u;
var pred = Predicate.False<User>();

if (type.HasFlag(IdentifierType.Username))
    pred = pred.Or(u => u.Username == identifier);

if (type.HasFlag(IdentifierType.Windows))
    pred = pred.Or((u => u.WindowsUsername == identifier);

return query.Where(pred.Expand()).FirstOrDefault();
// or return query.AsExpandable().Where(pred).FirstOrDefault();

Para esto es Expand:

La canalización de procesamiento de consultas de Entity Framework no puede manejar expresiones de invocación, por lo que debe llamar a AsExpandable en el primer objeto de la consulta. Al llamar a AsExpandable, activa la clase de visitante de expresión de LINQKit que sustituye las expresiones de invocación con construcciones más simples que Entity Framework pueda entender.

O: sin ella una expresión es Invoked, lo que provoca una excepción en EF:

El tipo de nodo de expresión LINQ 'Invoke' no se admite en LINQ to Entities.

Adición posterior:

Existe un generador de predicados alternativo que hace lo mismo pero sin Expandir: http://petemontgomery.wordpress.com/2011/02/10/a-universal-predicatebuilder/

Gert Arnold avatar Jan 31 '2013 09:01 Gert Arnold