2016-02-12 76 views
1

我正在使用最新版本的NHibernate,最近我偶然發現了一個有趣的問題。在某些情況下ORM額外的計算列?

比方說,我有一個名爲Profile的表,我想要接收我的所有配置文件的列表。但是,有了它,我有一個名爲CanDelete的計算列,它禁止在(例如)正在使用的情況下刪除配置文件。

但是,這CanDelete計算列不是我的實體的一部分,我不想污染實體,當我在這種情況下只需要CanDelete值 - 並且對每個配置文件單獨計算它太慢。

有沒有在NHibernate的方式執行某些查詢並獲取該查詢的行作爲對象,但然後以某種方式獲取一個額外的計算列以及?

假設我正在使用N層體系結構。在表示層中,我需要一個所有配置文件的列表(並且對於每個配置文件,我是否可以刪除它)。我的業務邏輯層和數據訪問層如何看起來像?

現在在我的資源庫中,我有一個GetProfiles方法,然後我運行了一個CanDeleteProfile方法,用於獲取每個配置文件。但就像我上面提到的那樣,它太慢了。我可以創建一個GetProfilesWithCanDeleteStatus方法,但這需要我創建一個專門的實體,並在其上包含該計算列。

當我不想在配置文件列表中擊中O(n^2)性能時,如何以適當方式構建此建議,您有什麼建議?我想避免n + 1問題。

我不一定在尋找一個NHibernate解決方案(我標記了NHibernate,因爲它可能有這種類型的東西的一些特定的工具),並歡迎其他ORM的一般解決方案。

回答

0

我有一個想法可能對你有好處,但它不會是一個完美的想法,因爲你設計你的程序的方式都有缺點。

我建議你更改該列的定義CanDelete,這樣它就像該實體中的任何其他列(不在運行時計算)和布爾類型,但不會破壞需求。

通過這樣做,它會像db中的任何其他簡單的Select - 這非常快。

現在,棘手的部分是確保該列將指示(在任何時候需要)它是否已被使用(以及是否可以刪除)。

因爲如果使用Profile實體(並且可以刪除),我不知道計算的方式,但很難說清楚如何精確設計DAL和BL,但指導原則是: 在其他每個地方更改DB(該實體或其他實體)中的一個狀態,該狀態可能會改變您使用函數封裝的列CanDelete以再次計算該值以驗證其狀態並在需要時更改它。

如果您確保每次在BL中更改其中一列CanDelete的計算方式,那麼您確保CanDelete列始終爲真。

這種方法的缺點是: 1。它會在程序員需要時不使用封裝函數的時候出錯。 2.它假設這個應用程序是唯一一個改變這個數據庫。 3.從管理工作室或腳本插入原始數據時必須小心。

我希望它對你的BL好。