2010-05-24 17 views
10

Sto costruendo una libreria di funzioni per una delle mie classi L2S principali, che restituiscono un bool per consentire il controllo di determinate situazioni.LINQ to SQL: NOTing un'espressione precostruita

Esempio:

Expression<Func<Account, bool>> IsSomethingX = 
     a => a.AccountSupplementary != null 
     && a.AccountSupplementary.SomethingXFlag != null 
     && a.AccountSupplementary.SomethingXFlag.Value; 

Ora per interrogare in cui questo non è vero, non posso fare questo:

var myAccounts= context.Accounts 
     .Where(!IsSomethingX); // does not compile 

Tuttavia, utilizzando la sintassi dalla classe PredicateBuilder, sono venuto con questo:

public static IQueryable<T> WhereNot<T>(this IQueryable<T> items, 
     Expression<Func<T, bool>> expr1) 
{ 
    var invokedExpr = Expression.Invoke(expr1, expr1.Parameters.Cast<Expression>()); 
    return items.Where(Expression.Lambda<Func<T, bool>> 
      (Expression.Not(invokedExpr), expr1.Parameters)); 
} 

var myAccounts= context.Accounts 
     .WhereNot(IsSomethingX); // does compile 

che produce effettivamente l'SQL corretto.

Questo sembra una buona soluzione, e c'è qualcosa di cui ho bisogno di essere a conoscenza che potrebbe causare problemi in futuro?

risposta

4

Ho scritto un codice di prova utilizzando il metodo di estensione WhereNot e sembra buono. La soluzione di @ Stephan funziona anche, ma sceglierei la leggibilità del metodo di estensione.

+0

+1, la soluzione descritta è soddisfacente e più semplice da utilizzare. –

3
var compiled = IsSomethingX.Compile(); 
var myAccounts = context.Accounts.Where(x => !compiled(x)); 
+0

Grazie per l'alternativa. – cjk