2012-06-25 10 views
6

Ich spiele mit RavenDb und frage mich, ob ich etwas offensichtlich fehlen.Passing ravendb Abfrage als Func <T, bool> funktioniert nicht

Sache ist, dass, wenn ich Abfrage wie folgt vorbei bin:

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

Es funktioniert ok, wenn ich gleichwertig Schreiben bin (IMO) mit Func<T, bool>, es stürzt nicht ab, sondern Abfrage fehlt, wo Bedingung:

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 gibt es mag:

query = start = 0 pagesize = 5 Aggregation = Keine sort = -CreatedAt

Update: Es funktioniert, wenn ich unter Verwendung des Ausdrucks bin statt Func, so dachte ich, kann ich erinnere mich über Func und Linq etwas falsch sein, so schrieb ein einfacher Test:

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

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

So, jetzt ist es nur noch die Frage, warum Raven Db Query Builder unterschiedlich wirkt.

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

Und ändern Where(x => selector(x))-Where(selector): ein Expression statt

Antwort

9

Versuchen Sie es mit.

Ein Expression ist erforderlich, da RavenDb einen Ausdrucksbaum daraus erstellen kann, der es ermöglicht, die Logik in Datenbankabfragen zu übersetzen. Es kann keinen Ausdrucksbaum von einer Func<Post, bool> erstellen, also könnte es entweder ignorieren, eine Ausnahme werfen oder was auch immer die Ersteller von RavenDb angegeben haben.

+0

Ich habe Frage aktualisiert, es funktioniert mit Ausdruck. – Giedrius

+0

@Giedrius Ich fügte meiner Antwort eine kurze Erklärung hinzu. – Botz3000

3

Als Antwort auf das Update, gibt es erhebliche Unterschiede im Verhalten zwischen Func<> auf IEnumerable<> und Expression<Func<>> auf IQueryable<> die syntaktisch identisch aussehen. Dies ist nicht nur Raven, sondern auch eine Quelle wie LINQ to SQL oder Entity Framework.