题
我有一个包含“标签”列表的文档类。是这样的:
class Item {
string Name { get; set; }
List<string> Tags {get; set;}
}
现在我想为RavenDB创建一个查询,递给我的所有资料的标签列表过滤。当使用实体框架,我设法通过这样的事情要做到这一点:
var query = GetQueryable();
foreach (var tag in tags)
{
query = query.Where(i => i.Tags.Contains(tag));
}
不过,这似乎并不与RavenDB工作时,很可能是因为含有不被支持。我也尝试使用任何重写它,(Where(i => i.Tags.Any(t=>t == tag))
),但给了我一个奇怪的例外:
Unable to cast object of type
'System.Linq.Expressions.PrimitiveParameterExpression`1[System.String]'
to type 'System.Linq.Expressions.MemberExpression
任何伟大的想法?我这样做完全错了?
解决方案
包含确实还不支持(或许是应该的,但这是另一回事完全 - 我们才真正增加对各运营商的支持时,它的要求)
作为对任何多次查询,我假设你正在试图做的动态数据和要实现的东西像
"X OR Y OR Z"
这是一个棘手的一个,并且默认的LINQ提供程序将聚合这些多个WHERE子句与AND,所以你的例子看起来像
"X AND Y AND Z"
这显然会永远是这种情况。
这一个你最好的选择是下降到了Lucene查询(至少目前如此),做这样的事情:
var results = s.Advanced.LuceneQuery<Item>()
.Where(string.Format("Tags,:({0})", string.Join(" OR ", tags)));
有意义吗?
上面看起来像查询
"Tags,:(X OR Y OR Z)"
注: “标签,” INFORMS RavenDB该标签是一个数组
好,[编辑]!
在最简单的办法让你真正的要的是做这些方针的东西。
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,你可以做这样的事情:
var results = s.Advanced.LuceneQuery<Item, WhateverYouCalledThatIndex>()
.Where(string.Format("Tags:({0})", string.Join(" AND ", tags)));
现在,事情要注意的
Tags = doc.Tags
将序列化整个阵列成一个巨大斑点,因为它只是串,这将在这个例子中工作。
我在看这表达更好的方法,这是不可能的,我们会想出这样做的LINQ十岁上下的方式,因为它并没有真正跨地图很好 - 但它的是的一个答案,将工作:)
我想我会很喜欢能够至少做
Map = docs => from doc in docs
select new
{
Tags = String.Join(" ", doc.Tags)
},
(这是行不通的,所以不要尝试),但它是一个比较明确你想要达到的目标。
不隶属于 StackOverflow