我在 RavenDB 中有以下实体集合:
public class EntityA
{
public string Id { get; set; }
public string Name { get; set; }
public string[] Tags { get; set; }
}
public class EntityB
{
public string Id { get; set; }
public string Name { get; set; }
public string[] Tags { get; set; }
}
唯一共享的是 Tags
集合:EntityA
的标签可能存在于 EntityB
中,因此它们可能相交。
如何检索每个 EntityA
与 EntityB
有交叉标签,其中 EntityB
的 Name
属性是等于给定值?
最佳答案
嗯,这是一个困难的问题。要做到这一点,您需要两个级别的减少 - 一个通过标签扩展您的结果,另一个通过 id 将其折叠回去。 Raven 没有简单的方法来做到这一点。
您可以使用变换伪造它。唯一的问题是您将拥有 skipped items在你的结果集中,所以确保你知道 how to deal with those .
public class TestIndex : AbstractMultiMapIndexCreationTask<TestIndex.Result>
{
public class Result
{
public string[] Ids { get; set; }
public string Name { get; set; }
public string Tag { get; set; }
}
public TestIndex()
{
AddMap<EntityA>(entities => from a in entities
from tag in a.Tags.DefaultIfEmpty("_")
select new
{
Ids = new[] { a.Id },
Name = (string) null,
Tag = tag
});
AddMap<EntityB>(entities => from b in entities
from tag in b.Tags
select new
{
Ids = new string[0],
b.Name,
Tag = tag
});
Reduce = results => from result in results
group result by result.Tag
into g
select new
{
Ids = g.SelectMany(x => x.Ids),
g.First(x => x.Name != null).Name,
Tag = g.Key
};
TransformResults = (database, results) =>
results.SelectMany(x => x.Ids)
.Distinct()
.Select(x => database.Load<EntityA>(x));
}
}
另请参阅完整的单元测试 here .
还有另一种方法,但我还没有测试过。那将是使用 Indexed Properties Bundle进行第一遍,然后将这些结果映射到第二遍。我正在对此进行总体试验,如果可行,我会用结果更新此答案。
关于c# - 非标识符属性上的 RavenDB 跨实体查询匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14322959/