2012-04-04 21 views
6

Ho una classe di accesso ai dati che mi ci è voluto un po 'per funzionare. Per la mia app, ho bisogno di ottenere diversi tipi di tabelle di SQL Server in cui la clausola WHERE differisce solo per il nome della colonna: alcune colonne sono read_time, altri sono ReadTime, e gli altri sono LastModifiedTime. Così ho pensato di passare la clausola WHERE quindi non avevo bisogno di creare un nuovo metodo per 50 tabelle diverse. Sembra semplice e funziona, ma non capisco qualcosa.Perché Func <> ed Expression <Func<>> Intercambiabile? Perché uno lavora nel mio caso?

Questo metodo, con Expression <> come parametro, funziona:

internal List<T> GetObjectsGreaterThanReadTime<T>(Expression<Func<T, bool>> whereClause) where T : class 
{ 
    Table<T> table = this.Database.GetTable<T>(); 
    IEnumerable<T> objects = table.Where(whereClause); 

    return objects.ToList(); 
} 

Ora, stavo cercando in questo modo (in basso) per un po ', e sarebbe solo appendere sull'ultima riga (ToList()). Innanzitutto, perché questo dovrebbe essere compilato? Voglio dire, perché Expression e Func possono essere usati indifferentemente come parametro? Quindi, perché Expression funziona e la versione di Func si blocca?

Nota: L'unica differenza tra il metodo di cui sopra e questo è il parametro metodo (Expression vs. Func).

internal List<T> GetObjectsGreaterThanReadTime<T>(Func<T, bool> whereClause) where T : class 
{ 
    Table<T> table = this.Database.GetTable<T>(); 
    IEnumerable<T> objects = table.Where(whereClause); 

    return objects.ToList(); 
} 
+3

Questo, in combinazione con la risposta (s) è di per sé una buona risposta ad alcuni dei "qual è il punto di un albero di espressione?" stile di domande. +1 Q & A –

risposta

12

La versione Expression chiama Queryable.Where che genera un albero di espressione, che (quando enumerate da ToList) viene tradotta a SQL ed eseguito sul server di database. Presumibilmente, il server del database si avvarrà di un indice basato sui criteri del filtro, per evitare di leggere l'intera tabella.

La versione Funz chiama Enumerable.Where che (quando enumerate da ToList) carichi l'intera tabella (quello che percepiscono come un blocco) e poi esegue i criteri di filtro contro gli oggetti in memoria.

+0

Ahhhhhhhhhhhh ... NICE. Ha un senso totale. Grazie! –

Problemi correlati