2010-04-18 123 views
1

這裏的問題包括將用LINQ寫成的語句翻譯成SQL語法成NHibernate的等價物。在LINQ to SQL中的代碼看起來像這樣:使用NHibernate的HQL進行多個內部連接的查詢

var whatevervar = from threads in context.THREADs 
          join threadposts in context.THREADPOSTs 
          on threads.thread_id equals threadposts.thread_id 
          join posts1 in context.POSTs 
          on threadposts.post_id equals posts1.post_id 
          join users in context.USERs 
          on posts1.user_id equals users.user_id 
          orderby posts1.post_time 
          where threads.thread_id == int.Parse(id) 
          select new 
          { 
           threads.thread_topic, 
           posts1.post_time, 
           users.user_display_name, 
           users.user_signature, 
           users.user_avatar, 
           posts1.post_body, 
           posts1.post_topic 
          }; 

它本質上是試圖抓住給定的論壇主題內的職位名單。我已經能夠想出(與本網站的用戶有幫助的幫助下)爲NHibernate的最好的是:

var whatevervar = session.CreateQuery("select t.Thread_topic, p.Post_time, " + 
               "u.User_display_name, u.User_signature, " + 
               "u.User_avatar, p.Post_body, p.Post_topic " + 
               "from THREADPOST tp " + 
               "inner join tp.Thread_ as t " + 
               "inner join tp.Post_ as p " + 
               "inner join p.User_ as u " + 
               "where tp.Thread_ = :what") 
               .SetParameter<THREAD>("what", threadid) 
               .SetResultTransformer(Transformers.AliasToBean(typeof(MyDTO))) 
               .List<MyDTO>(); 

但是,這並不解析很好,抱怨別名連接表是空引用。 MyDTO是輸出的自定義類型:

public class MyDTO 
{ 
    public string thread_topic { get; set; } 
    public DateTime post_time { get; set; } 
    public string user_display_name { get; set; } 
    public string user_signature { get; set; } 
    public string user_avatar { get; set; } 
    public string post_topic { get; set; } 
    public string post_body { get; set; } 
} 

我出出主意,並同時通過直接的SQL查詢這樣做是可行的,我希望做正確,沒有擊敗使用的目的ORM。

在此先感謝!

編輯:

數據庫看起來是這樣的:http://i41.tinypic.com/5agciu.jpg(還不能發表圖片。)

回答

0

當我想要一個HQL查詢返回一個自定義類型,像你一樣,我總是做像這樣:

select new MyDTO (t.Thread_Topic, p.Post_time, u.User_Display_Name, ....) 
from ... 

我會檢查我的一些代碼,但我認爲,我甚至不使用AliasToBeenTransformer在這種情況下。 我不知道,因爲我主要使用NHibernate的ICriteria API(並且在使用這個API時,確實需要在執行此類操作時指定resulttransformer)。

NB:我覺得很奇怪(或相當尷尬)看到財產名下劃線...

+0

奇怪的名字是由NConstruct Lite生成的XML的結果,我用它來製作ORM文件和其他東西。主鍵從「smth_id」更改爲「Id」,外鍵從「smth_id」更改爲「Smth_」。 – 2010-04-18 10:07:30

0

HQL是你的對象查詢,而不是你的表!

在您的HQL中,我看到類tp和該類的屬性tp.Thread_之間的聯接。你應該區分SQL和HQL。將HQL視爲對象TP上的查詢,而不是基礎表結構上的查詢。你能發佈你的域模型(你的對象之間的關係),以便我們可以幫助你嗎?

感謝您的照片。但是:它看起來像你的對象是你的表的副本,我不認爲這是你的想法?例如:我會認爲線程和帖子之間的多對多關係會使用Hibernate進行映射。如果是這樣的話,你可以加入帖子而不必擔心中間對象threadpost,事實上,這只是保持這些對象之間的關係,對嗎?

換句話說;用帖子列表裝飾你的線程對象,並用線程列表裝飾帖子對象。

[裝飾] 即將線程列表作爲屬性放在您的發佈類中,並將帖子列表作爲屬性添加到您的線程類中。你在尋找的是nhibernate映射文件的多對多關係。這意味着您不需要映射類中的多對多表,只映射帖子和線程類的關係。

+0

是的,我會立即編輯它。 – 2010-04-18 10:05:35

+0

我不知道NHibernate的HQL能夠在沒有中間表的情況下完成這些類型的關係 - 我知道我不能在常規SQL中這樣做,而沒有指出THREADPOST擁有THREAD和POST之間的關聯。 我不知道你的意思是「裝飾」。你能解釋一下嗎? – 2010-04-18 21:57:39

+0

他的裝飾意味着除了直接的表格屬性之外,還會向實體類中添加更多內容。所以用戶有多個帖子,所以將IList 添加到您的用戶級別等。 – 2010-04-22 19:36:45