Passing a ravendb request as Func <T, bool> does not work

I play with RavenDb and wonder if I am missing something obvious.

The fact is that if I pass the request as follows:

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

It works fine if I write the equivalent (IMO) using Func<T, bool> , it does not crash, but the request is absent when the condition is:

  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 displays it like this:

request = start = 0 PAGESIZE = 5 no aggregation = None sort = -CreatedAt

Update: It works if I use an expression instead of Func, so I thought that maybe I remember something wrong about Func and Linq, so I 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 the only question is why the Raven Db query builder acts differently.

+6
source share
2 answers

Try using Expression instead:

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

And change Where(x => selector(x)) to Where(selector) .

Expression required because RavenDb can build an expression tree from it, which allows it to translate logic into database queries. He cannot build an expression tree from Func<Post, bool> , so he can either ignore it, or issue exeption, or whatever is specified by the creators of RavenDb.

+9
source

In response to your update, there are significant behavioral differences between Func<> on IEnumerable<> and Expression<Func<>> on IQueryable<> , which look syntactically the same. This is not only Raven, but also any IQueryable<> source, such as LINQ to SQL or Entity Framework.

+3
source

Source: https://habr.com/ru/post/918947/


All Articles