Reputation: 79
My code like bellow:
This Main class :
public class Product {
public string Id { set; get; }
public IList<Attr> Attributes { set; get; }
}
This child class of main class :
public class Attr
{
public string Key { set; get; }
public object Value { set; get; }
}
Filter item class:
public class Filter
{
public CompareType Type { set; get; }
public string Key { set; get; }
public object Value { set; get; }
}
Linq extension fuction for querying :
public static class LINQExtension
{
public static bool isMatch(this Product prod, this List<Filter> filters)
{
foreach(Filter F in filters){
Attr attribute = prod.Attributes.Any(A => A.Key == F.Key);
switch(F.Type){
case CompareType.CONTAIN: return ((string)attribute.Value).Contains(F.Value);
case ....
default: return false;
}
}
}
}
Filtering products result: (Not working)
public ActionResult FilterProducts(string word, decimal min, decimal max){
List<Filter> Conditions = new List<Filter> {
new Filter {Key = "Price", Type = CompareType.BETWEEN, Value = new decimal[] {min, max} },
new Filter {Key = "Title", Type = CompareType.CONTAIN, Value = word }
...
};
var Result = Session.Query<Product>().Where(P => P.isMatch(Conditions)).ToList();
return View(Result);
}
When it tried to run give errors like below:
{"Could not understand expression: .Where(P => P.isMatch(value(App.Controllers.HomeController+<>c__DisplayClass2).Conditions)).ToList()"}
Upvotes: 2
Views: 680
Reputation: 880
In general, RavenDB's linq provider implementation is not equal to Linq-to-Objects provider. Under the hood, Raven's client API serializes linq query experssion to Lucene query, then makes a REST call to server with that query. (You can use Fiddler to see it happen)
For example, given a database named Test with Northwind sample data and the query code (and assuming you have Fiddler active)
using (var store = new DocumentStore
{
Url = "http://localhost.fiddler:8080",
DefaultDatabase = "Test"
})
{
store.Initialize();
using (var session = store.OpenSession())
{
var result = session.Query<Order>().Where(x =>
x.Company == "companies/58" && x.Freight < 30m).ToList();
}
}
you will see the following REST call to the server (after url decoding)
http://localhost:8080/databases/Test/indexes/dynamic/Orders?&query=Company:companies/58 AND Freight_Range:{* TO Dx30}&pageSize=128&SortHint-Freight_Range=Double
What you see highlighted in the url is Linq query "serialized" into Lucene query.
In your case the error that you are seeing is simply Raven's linq implementation cannot understand how to transform your custom code into Lucene query
Upvotes: 1