2011-10-03 88 views
1

我正在使用.NET MVC 3和PetaPoco構建一個共享數據庫的多租戶應用程序。 租戶ID(以及其他信息)在登錄時保存在FormsAuth cookie中,並且可通過BaseController屬性提供給所有控制器。大多數表格(除了主要的'租戶'表格之外)包括一個TenantId列。動態使用WHERE子句注入PetaPoco

而不是手動添加'WHERE TenantId = X'到要素表上的所有CRUD,有沒有一種方法可以在執行之前動態地將其添加到查詢中?換句話說,也許維護一個表的列表,如果查詢是針對其中一個表的,那麼在TenantId過濾器中動態添加?

當然好處是它不需要手動添加過濾器,從而減少了被忽略的機會。我確實發現了一個example using NHibernate,我懷疑可以重新使用。我正在使用Ninject以防有所作爲。

+0

什麼樣的數據,你試圖存儲與您的應用程序。通過這種方式使用動態SQL可能存在安全/ SQL注入風險 –

+0

一般來說,是的,但我們真的使用參數化的SQL(默認情況下是PetaPoco),所以這不應該成爲問題。我沒有在帖子中提及它與實際問題無關。但謝謝你指出:) – seekay

+0

好交易。我對PetaPoco並不熟悉,所以當我看到它時,我首先受到了折磨:) –

回答

0

Database類有一個OnCommandExecuting方法,您可以在自己的子類中重寫該方法,並在執行之前按照您希望的那樣修改sql。我們使用此功能在Sql Server和Oracle之間轉換isnull/nvl。

你可以在sql中留下一個標記並將其替換。

+0

謝謝 - 那可行。但是,如果IDbCommand具有JOIN,並且您只希望篩選器應用於某些表,那麼它可能會變得棘手。標記可能會克服這一點,除了如果我在sql中添加標記,我還可以直接添加TenantId過濾器(因爲忘記「添加」的開發人員的'問題'仍然存在)。我想我可能會選擇GetByTenant(而不是Get),除非有更好的解決方案。謝謝你的幫助! – seekay

+0

確實如此,但如果提及某個表格,您還可以檢查標記是否存在,否則會拋出異常。我還使用了一個幫助函數,它適用於exists子句,並在子句中使用comment/* SECURITY */etc,然後在執行之前檢查它,否則拋出異常。 – Schotime