C#在Linq中动态构建where子句?对于RavenDB

时间:2015-07-20 22:07:47

标签: c# linq ravendb

我的代码如下:

这个主要课程:

public class Product {
    public string Id { set; get; }
    public IList<Attr> Attributes { set; get; }
}

这个主要类的子类:

public class Attr
{
    public string Key { set; get; }
    public object Value { set; get; }
}

过滤项目类:

public class Filter
{
    public CompareType Type { set; get; }
    public string Key { set; get; }
    public object Value { set; get; }
}

Linq扩展功能查询:

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;
            }
        }
    }

}

过滤产品结果:(不工作)

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);
}

当它试图运行时给出如下错误:

{"Could not understand expression: .Where(P => P.isMatch(value(App.Controllers.HomeController+<>c__DisplayClass2).Conditions)).ToList()"}

1 个答案:

答案 0 :(得分:1)

通常,RavenDB的linq提供程序实现不等于Linq-to-Objects提供程序。 在引擎盖下,Raven的客户端API将linq查询experssion序列化为Lucene查询,然后使用该查询对服务器进行REST调用。 (你可以使用Fiddler看到它发生)

例如,给定一个名为Test with Northwind示例数据和查询代码的数据库(假设您有Fiddler激活)

  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();                    
            }
        }

您将看到以下对服务器的REST调用(在解码网址后)

http:// localhost:8080 / databases / Test / indexes / dynamic / Orders?&amp; query = Company:companies / 58 AND Freight_Range:{* TO Dx30} &amp; pageSize = 128&amp; SortHint- Freight_Range =双

您在网址中突出显示的内容是Linq查询&#34;序列化&#34;进入Lucene查询。

在您的情况下,您看到的错误只是Raven的linq实现无法理解如何将自定义代码转换为Lucene查询