2009-03-24 26 views
7

Ho metodo di estensione:Modificare il parametro da funzione lambda a un'espressione lambda

public static IQueryable<TResult> WithFieldLike<TResult>(
    this IQueryable<TResult> query, 
    Func<TResult, string> field, 
    string value) 
{ 
    Expression<Func<TResult, bool>> expr = 
     trans => field(trans).Contains(value); 
    return query.Where(expr); 
} 

ho bisogno di parametri cambiamento di digitare: Espressione>. Sarà qualcosa di simile.

public static IQueryable<TResult> WithFieldLike<TResult>(
    this IQueryable<TResult> query, 
    Expression<Func<TResult, string>> field, 
    string value) 
{ 
    Expression<Func<TResult, bool>> expr = ??? 
    return query.Where(expr); 
} 

La chiamata di questo metodo è:

var query7 = query.WithFieldLike(trans => trans.DeviceModelNumber, "ber_3"); 

Come devo costruire la "espr" in questo caso? Per favore aiuto.

+0

Si prega di aggiungere la lingua per i tag. – Svante

risposta

6

Deconstruct field e creare una nuova espressione, qualcosa di simile:

var expr = Expression.Lambda<Func<TResult, bool>> (
    Expression.Call (field.Body, typeof (string).GetMethod ("Contains"), 
     Expression.Constant (value)), field.Parameters) ; 

(a cura come da affinamento di Maxs nei commenti)

+0

Il punto è che non riesco a creare l'espressione "Contiene". Come si costruisce l'espressione "Uguali", lo so. – Maxs

+0

Oops, mi spiace risposta modificata –

+0

Grazie. Questo funziona perfettamente. – Maxs

1

Usa Compile per ottenere il lambda di nuovo fuori:

Expression<Func<TResult, bool>> expr = 
    trans => field.Compile()(trans).Contains(value); 

Edit: Ops - il mio compilatore aria me non è riuscita. Dopo la compilazione, ottieni il delegato. Ma è comunque necessario chiamarlo per ottenere la stringa da chiamare Contains.

+0

Errore di compilazione: 'System.Func ' non contiene una definizione per 'Contains' e nessun metodo di estensione 'Contains' che accetta un primo argomento di tipo 'System.Func ' potrebbe essere trovato (ti manca una direttiva using o un riferimento di assembly?) – Maxs

+0

@Maxs: Sì - ho un po 'rovinato l'intera parte "convertirlo in un'altra espressione". Il punto si alza però - usa Compile per ottenere il lambda, e usalo normalmente. –

4

Avrete bisogno di usare Expression.Invoke; qualcosa di simile (non testata):

public static IQueryable<TResult> WithFieldLike<TResult>(
    this IQueryable<TResult> query, 
    Expression<Func<TResult, string>> field, 
    string value) 
{ 
    var param = Expression.Parameter(typeof(TResult), "x"); 
    var expr = Expression.Lambda<Func<TResult, bool>>(
     Expression.Call(Expression.Invoke(field, param), 
      "Contains", null, Expression.Constant(value)), param); 

    return query.Where(expr); 
} 

(edit: fissa)

+1

Grazie. Anche questo funziona. Ma genera espressioni incompatibili con la chiamata ADO.NET Data Services. – Maxs

+1

Devi amare la legge delle astrazioni che perdono ... funziona con alcuni ma non tutti ;-p –

Problemi correlati