使用RavenDB查询的动态参数

时间:2017-04-26 07:48:59

标签: c# linq ravendb

我正在尝试简化和压缩我的代码,并尽可能地消除代码重复。我有一个查询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));
        (...)
        }

我在编译时遇到了几个问题,即“是一个变量但是像一个类型一样使用”,并且因为编译器不能推断成员变量(NAME_0,NAME_1等)这一事实知道“即将到来”。 我怀疑这根本无法做到;但是,这会对代码维护产生影响,因为我必须为每种类型的查询创建不同的方法,或者创建一个相当大的方法。这些都不太吸引人,但我没有看到任何方法。

1 个答案:

答案 0 :(得分:0)

按类型过滤的一种好方法是在&#34; select&#34;中包含 Raven-Entity-Name 字段。索引的子句。 然后,您可以使用EntityType字段过滤类型。 您可以在内置的 Raven / DocumentsByEntityName 索引中看到此类索引的示例

因此,您的索引可能如下所示:

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),这将有效