2012-06-25 33 views
6

Tôi đang chơi với RavenDb và tự hỏi liệu tôi có thiếu điều gì đó hiển nhiên không.Truy cập truy vấn ravendb dưới dạng Func <T, bool> không hoạt động

Thing là, rằng nếu tôi đi qua truy vấn như thế này:

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

Nó hoạt động ok, nếu tôi đang viết tương đương (IMO) sử dụng Func<T, bool>, nó không sụp đổ, nhưng truy vấn là mất tích ở đâu điều kiệ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 kết quả đầu ra nó thích:

query = start = 0 PageSize = 5 tập hợp = Không sort = -CreatedAt

Cập nhật: Nó hoạt động nếu tôi đang sử dụng biểu thay vì Func, vì vậy tôi nghĩ có thể tôi nhớ một cái gì đó sai về Func và LINQ, vì vậy đã viết một thử nghiệm đơn giản:

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

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

Vì vậy, bây giờ, đó chỉ là câu hỏi tại sao trình tạo truy vấn Raven Db hoạt động khác.

Trả lời

9

Hãy thử sử dụng một Expression thay vì:

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

Và thay đổi Where(x => selector(x))-Where(selector).

An Expression là bắt buộc vì RavenDb có thể xây dựng một cây biểu thức từ nó, cho phép nó dịch logic thành truy vấn cơ sở dữ liệu. Nó không thể xây dựng một cây biểu thức từ một Func<Post, bool>, do đó, nó có thể bỏ qua nó, ném một ngoại lệ hoặc bất kỳ người tạo RavenDb nào được chỉ định.

+0

Tôi đã cập nhật câu hỏi, nó hoạt động với biểu thức. – Giedrius

+0

@Giedrius Tôi đã thêm một giải thích ngắn cho câu trả lời của tôi. – Botz3000

3

Để phản hồi cập nhật của bạn, có sự khác biệt đáng kể về hành vi giữa Func<> trên IEnumerable<>Expression<Func<>> trên IQueryable<> trông giống hệt cú pháp. Đây không chỉ là Raven, mà là bất kỳ nguồn IQueryable<> nào chẳng hạn như LINQ to SQL hoặc Entity Framework.

Các vấn đề liên quan