2012-04-04 19 views
6

Tengo una clase de acceso a datos que me tomó un tiempo para ponerme a trabajar. Para mi aplicación, necesito obtener diferentes tipos de tablas de SQL Server donde la cláusula WHERE solo difiere por el nombre de la columna: algunas columnas son read_time, otras son ReadTime y otras son LastModifiedTime. Así que pensé en pasar la cláusula WHERE, así que no tuve que crear un nuevo método para 50 tablas diferentes. Parece simple, y funciona, pero no entiendo nada.¿Por qué son Func <> y Expresión <Func<>> Intercambiables? ¿Por qué uno trabaja en mi caso?

Este método, con la expresión <> como parámetro, funciona:

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

Ahora, yo estaba tratando de esta manera (abajo) durante un tiempo, y sería simplemente pasar el rato en la última línea (ToList()). Primero, ¿por qué compilaría esto? Quiero decir, ¿por qué Expression y Func se pueden usar indistintamente como un parámetro? Entonces, ¿por qué funciona Expression y la versión de Func simplemente se cuelga?

Nota: La única diferencia entre el método anterior y este es el parámetro del método (Expresión frente a 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

Esto, junto con la (s) respuesta (s) es en sí una muy buena respuesta a algunos de los "¿cuál es el sentido de un árbol de expresiones?" estilo de preguntas. +1 Q & A –

Respuesta

12

La versión Expresión llama Queryable.Where que genera un árbol de expresión, que (cuando enumerado por ToList) se traduce a SQL y se ejecuta en el servidor de base de datos. Es de suponer que el servidor de la base de datos se servirá de un índice basado en los criterios de filtro, para evitar leer toda la tabla.

versión Func La llama, que Enumerable.Where (cuando enumerado por ToList) cargas toda la tabla (lo que perciben como un bloqueo) y luego ejecuta el criterio de filtro contra los objetos en memoria.

+0

Ahhhhhhhhhhhh ... NIZA. Tiene sentido total ¡Gracias! –

Cuestiones relacionadas