使用NHibernate的HQL进行多个内部联接的查询

时间:2010-04-18 09:45:34

标签: c# .net nhibernate orm hql

这里的问题包括将用LINQ编写的语句转换为SQL语法,转换为NHibernate的等价语句。 LINQ to SQL代码如下所示:

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(无法发布图片。)

2 个答案:

答案 0 :(得分:0)

当我希望HQL查询返回自定义类型时,就像你一样,我总是这样做:

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

我必须查看我的一些代码,但我认为在这种情况下我甚至不使用AliasToBeenTransformer。 我不知道,因为我主要使用NHibernate的ICriteria API(当使用这个时,你确实需要在执行这种操作时指定resulttransformer)。

注意:我觉得在属性名称中看到下划线很奇怪(或者说很尴尬)......

答案 1 :(得分:0)

HQL是对您的对象的查询,而不是您的表!

在你的HQL中,我看到类tp和该类的属性tp.Thread_之间的连接。您应该区分SQL和HQL。将HQL视为对象TP的查询,而不是基础表结构。您可以发布您的域模型(您的对象之间的关系),以便我们可以帮助您吗?

谢谢你的照片。但是:看起来你的对象是你的表的副本,我不认为这是你的想法?例如:我认为线程和帖子之间的多对多关系将使用Hibernate进行映射。如果是这种情况,您可以将帖子与帖子连接起来,而不必费心中间对象的帖子,实际上,这只是持有这些对象之间的关系,对吗?

换句话说;用一个帖子列表装饰你的线程对象,并用一个线程列表装饰post对象。

[装饰] 这是将一个线程列表作为一个属性放在你的帖子类上,并将一个帖子列表作为一个属性放在你的线程类上。您正在寻找的是nhibernate映射文件的多对多关系。这意味着您不需要在类中映射多对多表,只需映射post和thread类的关系。