使用动态参数进行 RavenDB 查询
Use dynamic parameters for RavenDB query
我正在努力简化和压缩我的代码,并尽可能地消除代码重复。我有一个查询 RavenDB 集合的方法,查询需要适应我要查询的类型。这种类型根据传递给方法的参数而变化,where 子句也需要适应。
我有一个基本类型 AdministrativeArea,其他类型派生自它(Level1_AdministrativeAreas 到 Level5_AdministrativeAreas)。根据场景,我需要查询AdministrativeAreas,Level1_AdministrativeAreas等
我目前拥有的:
private void Merge(MergeLevel currentMergeLevel, IDocumentSession currentSession)
{
(...)
IQueryable<AdministrativeArea> query;
if (currentMergeLevel == MergeLevel.Level1)
query = currentSession.Query<AdministrativeArea, AdminAreaName>()
.Where(area => !string.IsNullOrEmpty(area.NAME_0) && !string.IsNullOrEmpty(area.NAME_1));
(...)
}
有没有办法将类型作为方法参数传递并将它们应用于查询,如下所示:
private void Merge(MergeLevel currentMergeLevel, IDocumentSession currentSession, Type requiredType, Type indexType)
{
(...)
IQueryable<requiredType> query;
if (currentMergeLevel == MergeLevel.Level1)
query = currentSession.Query<requiredType, indexType>()
.Where(area => !string.IsNullOrEmpty(area.NAME_0) && !string.IsNullOrEmpty(area.NAME_1));
(...)
}
我在编译时遇到了几个问题,即"is a variable but is used like a type",以及无法推断成员变量(NAME_0、NAME_1等)的事实,因为编译器不知道 "what's coming"。
我怀疑这根本做不到;但是,这对代码维护有影响,因为我必须为每种类型的查询创建不同的方法或创建一个相当大的方法。两者都不太吸引人,但我看不出有任何解决办法。
按类型过滤的一个好方法是在索引的 "select" 子句中包含 Raven-Entity-Name 字段。
然后您就可以使用 EntityType 字段来过滤类型。
你可以在内置的 Raven/DocumentsByEntityName index
中看到这种索引的例子
因此,您的索引可能如下所示:
from doc in docs
let entityType = doc["@metadata"]["Raven-Entity-Name"]
where entityType.EndsWith("_AdministrativeAreas")
select new
{
EntityType = entityType,
//the rest of the fields
}
请注意,如果您通过现有客户端 API 插入文档,这将有效(原始 REST API 不会自行添加 Raven-Entity-Name)
我正在努力简化和压缩我的代码,并尽可能地消除代码重复。我有一个查询 RavenDB 集合的方法,查询需要适应我要查询的类型。这种类型根据传递给方法的参数而变化,where 子句也需要适应。 我有一个基本类型 AdministrativeArea,其他类型派生自它(Level1_AdministrativeAreas 到 Level5_AdministrativeAreas)。根据场景,我需要查询AdministrativeAreas,Level1_AdministrativeAreas等
我目前拥有的:
private void Merge(MergeLevel currentMergeLevel, IDocumentSession currentSession)
{
(...)
IQueryable<AdministrativeArea> query;
if (currentMergeLevel == MergeLevel.Level1)
query = currentSession.Query<AdministrativeArea, AdminAreaName>()
.Where(area => !string.IsNullOrEmpty(area.NAME_0) && !string.IsNullOrEmpty(area.NAME_1));
(...)
}
有没有办法将类型作为方法参数传递并将它们应用于查询,如下所示:
private void Merge(MergeLevel currentMergeLevel, IDocumentSession currentSession, Type requiredType, Type indexType)
{
(...)
IQueryable<requiredType> query;
if (currentMergeLevel == MergeLevel.Level1)
query = currentSession.Query<requiredType, indexType>()
.Where(area => !string.IsNullOrEmpty(area.NAME_0) && !string.IsNullOrEmpty(area.NAME_1));
(...)
}
我在编译时遇到了几个问题,即"is a variable but is used like a type",以及无法推断成员变量(NAME_0、NAME_1等)的事实,因为编译器不知道 "what's coming"。 我怀疑这根本做不到;但是,这对代码维护有影响,因为我必须为每种类型的查询创建不同的方法或创建一个相当大的方法。两者都不太吸引人,但我看不出有任何解决办法。
按类型过滤的一个好方法是在索引的 "select" 子句中包含 Raven-Entity-Name 字段。
然后您就可以使用 EntityType 字段来过滤类型。
你可以在内置的 Raven/DocumentsByEntityName index
因此,您的索引可能如下所示:
from doc in docs
let entityType = doc["@metadata"]["Raven-Entity-Name"]
where entityType.EndsWith("_AdministrativeAreas")
select new
{
EntityType = entityType,
//the rest of the fields
}
请注意,如果您通过现有客户端 API 插入文档,这将有效(原始 REST API 不会自行添加 Raven-Entity-Name)