2011-09-19 112 views
1

我有一個使用NH 3.1的項目,並且迄今爲止一直使用QueryOver語法。NHibernate QueryOver值集合

該項目的一個方面是在一個組織範圍內的數據庫中,我擁有隻讀訪問權限並且使用了完全不同的DBMS(Oracle vs MSSQL)。所以我存儲從我的對象(FOOS)引用它們的對象(酒吧)使用標準的多對許多表

FooBars 
FooID int not null PK 
BarID int not null PK 

我的域對象,而不是具有Iset<Bar>,而不是具有手動映射的ISet<int> BarIDsFooBars表。這可以防止NH嘗試做不可能的事情,並且一直加入到Bars表中(如果我需要它們,我可以使用BarRepository.Get()來檢索Bars的細節,在這種情況下,我會't,因爲我只需要這些ID來篩選返回的對象列表)。

鑑於IList<int> SelectedBars我該怎麼寫QueryOver<Foo>其中BarIDs包含SelectedBars中的任何元素?

SQL類似

...FROM foos INNER JOIN foobars on foo.fooID = foobars.fooID WHERE barID IN (...) 

回答

0

所以3年後,我回來報告我是如何解決這個問題的。

public class Foo :Entity { 
    public virtual ISet<FooBar> BarIDs { get; protected internal set; } 
} ... 

public class FooBar :Entity { 
    protected internal FooBar() { } 
    protected internal FooBar(Foo f, int BarID) { ... } 
    public virtual Foo Foo { get; protected internal set; } 
    public virtual int BarID { get; protected internal set; } 
} 

這基本上是Stefan建議的內容,以及相關文章中的暗示。你只需要花費額外的實體和引用它的開銷。請記住,我正在存儲BarID而不是完整的Bar對象,因爲我正在處理兩個數據庫之間的硬邊界:Bars存儲在與Foos不同的平臺上的完全不同的數據庫中。否則,當然,你告訴Foo它有一個ISet<Bar>要好得多。

查找FOOS通過SelectedBarIDs是那麼容易的,就像Thilak建議:

session.QueryOver<Foo>().JoinQueryOver<FooBar>(f => f.BarIDs). 
    WhereRestrictionOn(b => b.BarID).IsIn(...)... 

這是一個有趣的問題,遇到像這樣的數據庫邊界的工作。我不能說我喜歡這樣做,但如果其他人要花時間維護一個酒吧列表並將其提供給我使用,那麼對我來說這將是一個巨大的浪費資源。因此,使用包裝類的低效率是一個非常簡單的成本。

1

嘗試:

session.QueryOver<Foo>() 
     .JoinQueryOver(x => x.FooBars) 
     .WhereRestrictionOn(x => x.BarId).IsIn(...) 
2

這是不可能的QueryOver。兩年前,我有一個similar question about filtering value collections。 (注意:QueryOver基於Criteria API)。

我不是100%確定,但它可能適用於HQL。它更強大。

您可能會在QueryOver條件中包含SQL語句。

我不明白你爲什麼不把它映射爲實體列表。有懶惰的加載以避免不必要的加載 - 雖然有時候會有一些折衷。您可以在不碰到數據庫的情況下訪問NH代理的ID。映射ID通常會讓生活變得更加困難。

+0

是的,我有這種徒勞的希望,也許事情會在兩年內發生改變。延遲加載將不起作用,因爲如果我不小心,它會嘗試訪問數據庫,然後嘗試將MSSQL數據庫中的表加入Oracle數據庫。但是我可以編寫一個只有ID作爲其唯一屬性的包裝類「DummyBar」......只需讓automapper忽略它即可。 –

+0

回到這兩個月之後...我曾嘗試編寫一個BarProxy類,但是當它開始查詢「找到與此欄有關係的foos」時,SQL試圖加入BarProxy表,a)不存在,b)即使它確實存在也是空的(真實數據在外部數據庫中)。所以我想現在我們會嘗試HQL或原始SQL。 –