2014-11-24 48 views
0

用例:編寫一個通用的功能像使用依賴型產生編譯錯誤

def tenantFilterQuery[T, Q <: Table[T]](t: Q, e: TableQuery[Q], id: Int)(implicit s: Session) :Query[Q,Q#TableElementType,Seq] = { 
    e.filter(_.tenantId === id) 
} 

我想補充編譯時情報,e.filter(_.tenantId === id)過濾器應只應用於如果通過T有一個名爲tenantId屬性否則它不會應用該過濾器,如果T沒有該屬性。

這可以解決與依賴路徑類型有或沒有使用無形?

第二步試圖拿出其中,當最後Query由一種方式,如果T一直屬性命名tenantId它會在編譯時失敗,如果沒有filtertenantId它。想一想第一個問題,我應該爲這個問題創建一個單獨的問題。

回答

0

第二個問題是更容易的一個:你可以使用結構類型T <: {def tenantId: Int},然後只能用這樣的T來調用它。

如果你想過濾器發生這些類型,而不是發生另一種類型,我想你可以通過提供一個隱式助手做到這一點?喜歡的東西:

sealed trait Helper[T]{ 
    def applyToQuery[Q <: Table[T]](e: TableQuery[Q]): TableQuery[Q] 
} 
trait LowPriorityHelper { 
    implicit def withoutTenantId[T] = new Helper[T] { 
    def applyToQuery[Q <: Table[T]](e: TableQuery[Q]): TableQuery[Q] = e 
    } 
} 
object Helper extends LowPriorityHelper { 
    implicit def withTenantId[T <: {def tenantId: Int}] = 
    new Helper[T] { 
     def applyToQuery[Q <: Table[T]](e: TableQuery[Q]): TableQuery[Q] = 
     e.filter(_.tenantId === id) 
    } 
} 

def doQuery[T: Helper] = { val e = ...; implicitly[Helper[T]].applyToQuery(e)...} 

withTenantIdHelperT具有tenantIdwithoutTenantId一個,否則將被傳遞。

+0

我不知道你正在使用這個數據庫庫,但它看起來像你需要'Q'包含'tenantId'。相同的技術應該可以工作。 – lmm 2014-11-25 08:01:21