0

我有這個clases映射在NHibernate的3.2 FluentNHibernate 1.3:NHibernate的LINQ和多對多映射

public class ClassA 
{ 
    public virtual Int32 Id{ get; } 
    .... 
    public ICollection<ClassB> ClassesB { get; } 
    public ICollection<ClassC> ClassesC { get; } 
} 

public class ClassB 
{ 
    public virtual Int32 Id{ get; } 
    .... 
    public ICollection<ClassA> ClassesA { get; } 
    public ICollection<ClassC> ClassesC { get; } 
} 

public class ClassC 
{ 
    public virtual Int32 Id{ get; } 
    .... 
    public ICollection<ClassA> ClassesA { get; } 
    public ICollection<ClassB> ClassesB { get; } 
} 

所有映射正常工作和spected。但是我需要用LINQ進行查詢,例如返回給定ClassB或ClassA實例中的所有ClassC實例,反之亦然。我需要在獲取ClassC列表之前不加載任何ClassB或ClassA實例,只需使用實例的ID進行查詢即可。我知道我可以加載,例如,一個ClassB實例,然後獲得ClassesC集合,但與我的應用程序desing我必須做到這一點,而不是這樣做,我會用這個東西,如在網格上分頁,和其他操作與尋呼不同。

在純SQL上,我可以通過簡單的連接查詢來做到這一點,但我不知道如何用LINQ來做到這一點。我不想要HQL或ICriteria的選項,它必須用LINQ(Extensions preferred)來完成,因爲應用程序使用的插件一定不知道NHibernate的存在。該插件接收一個IQueryable實例來進行查詢(這允許我們輕鬆地將核心應用程序移植到其他數據庫模式,比如NoSQL或其他什麼,甚至無需重新編譯插件或應用程序的其他部分)。

感謝您的幫助提前。

+0

順便說一句,使用'IQueryable'和'Linq2nHibrenate'可能會非常棘手。在爲插件提供'IQueryable'之前,你必須考慮三次。 – Akim 2012-07-18 08:16:26

+0

我使用NHibernate 3.2,它有LINQ「集成」,我沒有任何問題,用於其他「正常」查詢。這些插件是爲一個非常封閉的系統開發的,所有的插件都是由程序員開發的,應用程序只能由同一個「公司」使用,而不是用於多用途。插件將主要用於報告和文件生成。相信我,我向他們發出了關於這個問題的所有警告,但是我的客戶認爲這一定是這樣的,hehehehehehe。 – ElMangau 2012-07-18 09:39:36

+0

我只是給他們他們問四個問題,我做了我的部分警告他們(我甚至有一封由首席執行官簽名的信,以防萬一)。 我真的很感謝你對此的建議。 – ElMangau 2012-07-18 09:40:03

回答

0

默認情況下,在FluentNHibernate中HasMany會加載集合。你可以使用流利的語法來配置它。懶加載的

例子:

class ClassAMap : ClassMap<ClassA> 
{ 
    public ClassAMap() 
    { 
    // ... 
    // lazy loading using select 
    HasMany(x => x.ClassesB) 
     .LazyLoad() 
     .Fetch.Select() 
    // ... 
} 

,或者使用貪婪加載join

class ClassAMap : ClassMap<ClassA> 
{ 
    public ClassAMap() 
    { 
    // ... 
    // greedy loading using join 
    HasMany(x => x.ClassesB) 
     .Fetch.Join() 
    // ... 
} 

conventions

Table.Is(x => x.EntityType.Name + "Table") 
    DefaultLazy.Always() 

反正這個配置主題是相當複雜的,取決於如何準確你配置你的映射。 我建議你看看使用log4net的hHibernate SQL日誌來看SQL命令是由ORM生成的。

+0

非常感謝Akim,爲您的快速回答!我知道延遲加載的東西,並獲取映射和約定,但我需要它用IQueryable接口來做到這一點,我需要使用映射類的其他字段進行查詢。 例如:Session.Query ().Where(inst => inst.ClassC.Id == XXX && inst.ProcessStatus == ProcessStatusEnum.Pending).OrderBy ........ 類似的東西。 – ElMangau 2012-07-18 09:28:05

+0

這應該可以正常工作。只需*在日誌文件中檢查由ORM生成的SQL並調整映射*。你會有很多驚喜;) – Akim 2012-07-18 10:51:59