Clausola dynamic where (OR) in Linq alle Entities

Nel post qui ho imparato come creare una query dynamic utilizzando l’esecuzione differita di Linq. Ma la query utilizza effettivamente una concatenazione AND della condizione WHERE.

Come posso ottenere la stessa query ma con una logica OR?

A causa dell’enumerazione di Flags, la query dovrebbe cercare Username , WindowsUsername o entrambi :

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

Con PredicateBuilder di LINQKit puoi creare predicati dynamicmente .

 var query = from u in context.Users select u; var pred = Predicate.False(); 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(); 

Questo è ciò che l’ Expand è per:

La pipeline di elaborazione delle query di Entity Framework non può gestire le espressioni di chiamata, motivo per cui è necessario chiamare AsExpandable sul primo object nella query. Chiamando AsExpandable, si triggers la class di espressione visitatore LINQKit che sostituisce le espressioni di invocazione con costrutti più semplici che Entity Framework può comprendere.

Oppure: senza di essa un’espressione è Invoke d, che causa un’eccezione in EF:

Il tipo di nodo di espressione LINQ “Invoke” non è supportato in LINQ alle quadro.

Aggiunta successiva:

C’è un generatore di predicati alternativo che fa lo stesso, ma senza Expand: http://petemontgomery.wordpress.com/2011/02/10/a-universal-predicatebuilder/

Questo dovrebbe aiutare ..

Contiene query su più colonne

Sembra anche che ci sia un problema fondamentale nella progettazione del tavolo (correggimi se ho torto). Qual è lo scopo di IdentifierType nel tuo database?