I'm playing with RavenDb and wondering if I'm missing something obvious.
Thing is, that if I'm passing query like this:
var name = "test";
posts = RavenSession.Query<Post>()
.Where(x => x.Tags.Any(y => y == name))
.OrderByDescending(x => x.CreatedAt)
.Take(5);
It works ok, if i'm writing equivalent (IMO) using Func<T, bool>
, it does not crash, but query is missing where condition:
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 outputs it like:
query= start=0 pageSize=5 aggregation=None sort=-CreatedAt
Update: It works if I'm using expression instead of Func, so I thought may be I remember something wrong about Func and Linq, so wrote a simple test:
var range = Enumerable.Range(1, 50);
Func<int, bool> selector = x => x == 42;
var filtered = range.Where(x => selector(x));
So now it is only question why Raven Db query builder acts different.
Try using an Expression
instead:
Expression<Func<Post, bool>> selector = x => x.Tags.Any(y => y == name);
And change Where(x => selector(x))
to Where(selector)
.
An Expression
is required because RavenDb can build an expression tree from it, which allows it to translate the logic into database queries. It cannot build an expression tree from a Func<Post, bool>
, so it might either ignore it, throw an exeption or whatever the creators of RavenDb specified.
As a response to your update, there is significant behavioral differences between Func<>
on IEnumerable<>
and Expression<Func<>>
on IQueryable<>
that look syntactically identical. This is not just Raven, but any IQueryable<>
source such as LINQ to SQL or Entity Framework.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With