2012-06-25 12 views
6

Estoy jugando con RavenDb y me pregunto si me falta algo obvio.Al pasar la consulta ravendb como Func <T, bool> no funciona

La cosa es, que si yo estoy pasando consulta como esta:

var name = "test"; 
    posts = RavenSession.Query<Post>() 
     .Where(x => x.Tags.Any(y => y == name)) 
     .OrderByDescending(x => x.CreatedAt) 
     .Take(5); 

Funciona bien, si estoy escribiendo equivalente (OMI) usando Func<T, bool>, que no se desplome, pero no se encuentra en consulta condición:

var name = "test";  
Func<Post, bool> selector = x => x.Tags.Any(y => y == name); 
posts = RavenSession.Query<Post>() 
     .Where(x => selector(x)) 
     .OrderByDescending(x => x.CreatedAt) 
     .Take(5); 

Profiler salidas se siente:

consulta = inicio = 0 pageSize = 5 agregación = Ninguno tipo = -CreatedAt

Actualización: Funciona si estoy usando la expresión en lugar de Func, así que pensé que puede ser que recuerde algo raro en Func y LINQ, por lo que escribió una simple prueba:

var range = Enumerable.Range(1, 50); 

Func<int, bool> selector = x => x == 42; 
var filtered = range.Where(x => selector(x)); 

Así que ahora solo es cuestión de por qué el generador de consultas Raven Db actúa de manera diferente.

Respuesta

9

tratar de usar un Expression lugar:

Expression<Func<Post, bool>> selector = x => x.Tags.Any(y => y == name); 

Y cambiar Where(x => selector(x))-Where(selector).

Se requiere un Expression porque RavenDb puede construir un árbol de expresiones a partir de él, lo que le permite traducir la lógica a las consultas de la base de datos. No puede construir un árbol de expresiones desde Func<Post, bool>, por lo que puede ignorarlo, lanzar una excepción o lo que sea que hayan especificado los creadores de RavenDb.

+0

He actualizado la pregunta, funciona con expresión. – Giedrius

+0

@Giedrius Agregué una breve explicación a mi respuesta. – Botz3000

3

Como respuesta a su actualización, hay diferencias significativas entre el comportamiento Func<> en IEnumerable<> y Expression<Func<>> en IQueryable<> que se ven sintácticamente idéntica. Esto no es solo Raven, sino cualquier fuente IQueryable<>, como LINQ to SQL o Entity Framework.

Cuestiones relacionadas