2010-12-07 28 views
1

我有一個看起來像這樣的實體:如何在NHibernate中對異構集合執行OfType <>()。Count()?

public class Album 
{ 
    public virtual string Name { get; set; } 
    public virtual IEnumerable<Media> { get; set; } 

    public virtual IEnumerable<Picture> 
    { 
     get { return Media.OfType<Picture>(); } 
    } 

    public virtual IEnumerable<Video> 
    { 
     get { return Media.OfType<Video>(); } 
    } 

    public virtual IEnumerable<Audio> 
    { 
     get { return Media.OfType<Audio>(); } 
    } 
} 

哪裏Media是抽象基類和PictureVideoAudioMedia亞型,所以IEnumerable<Media>集合是異質的。

我有一個Album DTO,看起來像這樣:

public class AlbumDTO 
{ 
    public string Name { get; set; } 
    public int PictureCount { get; set; } 
    public int VideoCount { get; set; } 
    public int AudioCount { get; set; } 
} 

如果每個計數正在做<collection>.Count();填充。雖然這個代碼工作正常,我也得到了各媒體類型的數量,生成的SQL不太理想:

SELECT * FROM Media WHERE media.Album_id = 1 
SELECT * FROM Media WHERE media.Album_id = 2 
SELECT * FROM Media where media.Album_id = 3 

換句話說,它抓住所有Media從數據庫中,然後再進行OfType<T>.Count()之後在記憶中。問題是,如果我在所有Albums上執行此操作,它將從數據庫中選擇所有Media,這可能會有數千條記錄。最好,我希望看到這樣的事情(我使用的table-per-層次映射):

SELECT COUNT(*) FROM Media WHERE media.Album_id = 1 AND discriminator = 'Picture' 
SELECT COUNT(*) FROM Media WHERE media.Album_id = 1 AND discriminator = 'Video' 
SELECT COUNT(*) FROM Media WHERE media.Album_id = 1 AND discriminator = 'Note' 

有誰知道我怎麼可以配置NHibernate的做到這一點?或者我將不得不修改我的Album實體以獲得正確的行爲?

+0

發佈您的配置。你用Fluent Nhibernate? – Aliostad 2010-12-07 20:01:08

回答

2

首先,你的代碼不會編譯;你錯過了IEnumerable<Media>(我假設它是媒體)的屬性名稱,以及過濾器的屬性名稱。

其次,你必須瞭解有關發生了什麼。從這種行爲中,我確定你已經將你的Album與HasMany關係映射到Media。 NH默認加載,所以當你第一次從數據庫中獲取相冊時,Media被賦予一個名爲PersistentBag的NHibernate對象的引用。這只是一個看起來像IEnumerable的佔位符,並且在實際需要時持有填充真實列表的邏輯。它所能做的就是在調用其GetEnumerator()方法時(如果發生在幾乎每個Linq方法中),將記錄拉出到HBM中映射的記錄。所以,當你調用OfType時,你不再使用NHibernate IQueryable,它可以建立一個完全按照你想要的SQL語句。相反,你要求列表中你認爲已經擁有的每個元素,並且NHibernate遵守。

如果你想要的只是計數,你有一些選擇。最簡單的,如果可能的話,簡直是回到了會議,並要求在專輯上了一個全新的查詢:

session.Linq<Album>().Where(a=>a.Id = 1).Select(a=>a.Media.OfType<Picture>()).Count(); 

這將直接構建進入到數據庫並獲取記錄的計數的聲明。你不是懶惰加載任何東西,你要求知識庫提供一個計數,它知道如何直接轉換成SQL。

相關問題