LINQ查询多个包含/任何的RavenDB [英] Linq query with multiple Contains/Any for RavenDB

查看:183
本文介绍了LINQ查询多个包含/任何的RavenDB的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含标签列表的文档类。是这样的:

I have a document class that contains a list of "tags". Something like:

class Item {
  string Name { get; set; }
  List<string> Tags {get; set;}
}

现在我想创造RavenDB一个查询,递给我所有资料的标签列表过滤。当使用实体框架,我设法通过这样的事情要做到这一点:

Now I would like to create a query for RavenDB that hands me all items filtered by a list of tags. When using Entity Framework I managed to do this by something like this:

var query = GetQueryable();
foreach (var tag in tags)
{
   query = query.Where(i => i.Tags.Contains(tag));
}

然而,这似乎

不RavenDB工作,很可能是因为包含不支持..我也尝试过使用任何重写,(其中(i => i.Tags.Any(T =>吨==标签))),但给了我一个奇怪的异常:

However, this doesn't seem to work with RavenDB, most likely because Contains isn't supported.. I've also tried rewriting it using Any, (Where(i => i.Tags.Any(t=>t == tag))) but that gives me a strange exception:

Unable to cast object of type
'System.Linq.Expressions.PrimitiveParameterExpression`1[System.String]'
to type 'System.Linq.Expressions.MemberExpression

任何伟大的想法?我做这完全错了。

Any great ideas? Am I doing this completely wrong?

推荐答案

包含确实​​尚不支持(或许是应该的,但是这完全是另一回事? - 我们只有真正增加对各运营商的支持时,它的要求)

Contains is indeed not yet supported (Perhaps it should be, but that's another matter entirely - we only really add support for various operators when its asked for)

至于反对任何多个查询,我假设你正在试图做的动态数据,你想实现像

As for multiple queries against Any, I assume you're trying to do dynamic data and you want to achieve something like

"X OR Y OR Z"

这是一个棘手的,并拥有和,所以你的例子看起来像

That's a tricky one, and the LINQ provider by default will aggregate those multiple WHERE clauses with AND, so your example looks like

"X AND Y AND Z"

这显然会。从来没有出现这种情况。

Which will obviously never be the case.

这一个你最好的选择是下降到了Lucene查询(至少目前如此),做这样的事情:

Your best option for this one is to drop down to the Lucene query (at least for now) and do something like this:

var results = s.Advanced.LuceneQuery<Item>()
                   .Where(string.Format("Tags,:({0})", string.Join(" OR ", tags))); 

请有意义吗?

以上查询看起来像

"Tags,:(X OR Y OR Z)"

注:标签,通知RavenDB的标签是一个数组

好吧,!

让你真正的想最简单的方法的是做东西沿着这些路线

The easiest way to get what you actually want is to do something along these lines

                new IndexDefinition<Item, Item>()
                {
                    Map = docs => from doc in docs
                                  select new
                                  {
                                      Tags = doc.Tags
                                  },
                    Indexes = {{ x => x.Tags, FieldIndexing.Analyzed }}
                }.ToIndexDefinition(store.Conventions));



然后查询您的ANDS,你可以做这样的事情:

Then to query for your ands, you can do something like this:

                var results = s.Advanced.LuceneQuery<Item, WhateverYouCalledThatIndex>()
                   .Where(string.Format("Tags:({0})", string.Join(" AND ", tags)));

现在,事情需要注意的

       Tags = doc.Tags

将序列化整个阵列成一个巨大的一滴,因为它只是字符串,将在本例中工作。

Will serialize that entire array into one giant blob, as it's just strings that will work for this example.

我期待在表达这种更好的方法,这是不可能的,我们将拿出这样做,因为它并没有真正跨很好地映射的LINQ十岁上下的方式 - 但它的的答案,将工作:)

I am looking at better ways of expressing this, it is unlikely that we'll come up with a LINQ-ish way of doing this, as it doesn't really map across very well - but it is an answer that will work :)

我想我会很希望能够至少做

I think I'd quite like to be able to at least do

  Map = docs => from doc in docs
                                  select new
                                  {
                                      Tags = String.Join(" ", doc.Tags)
                                  },

(这将无法工作,所以不要尝试),但它是一个比较明确你想要达到的。

(This won't work so don't try it), but it is a bit more explicit about what you want to achieve.

这篇关于LINQ查询多个包含/任何的RavenDB的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆