2010-04-18 83 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