2017-04-26 67 views
0

我試圖簡化和壓縮我的代碼,並儘可能地消除代碼重複。我有一個查詢RavenDB集合的方法,查詢需要適應我要查詢的類型。此類型根據傳遞給方法的參數而變化,並且where子句也需要適應。 我有一個基礎類型AdministrativeArea,其他類型派生自(Level1_AdministrativeAreas到Level5_AdministrativeAreas)。根據不同的情況下,我需要查詢AdministrativeAreas,Level1_AdministrativeAreas等使用RavenDB查詢的動態參數

我目前有:

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

這不是很清楚,但嘗試使用泛型:void Merge (int currentMergeLevel ,IDocumentSession currentSession) – Embri

回答

0

按類型過濾的一種好方法是在索引的「select」子句中包含Raven-Entity-Name字段。 然後,您將能夠通過使用EntityType字段來過濾類型。 你可以看到這種指標的例子在內置烏鴉/ 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)

+0

邁克爾,這是一個有趣的方法 - 我沒有想到這一點!我結束了對泛型的熟悉,結果爲我的問題提供了一個解決方案。不過,我會玩弄你的建議方法。謝謝 ! –