简体   繁体   English

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

[英]Using NHibernate's HQL to make a query with multiple inner joins

The problem here consists of translating a statement written in LINQ to SQL syntax into the equivalent for NHibernate.这里的问题包括将用 LINQ to SQL 语法编写的语句转换为 NHibernate 的等效语句。 The LINQ to SQL code looks like so: 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
                          };

It's essentially trying to grab a list of posts within a given forum thread.它本质上是试图获取给定论坛线程中的帖子列表。 The best I've been able to come up with (with the help of the helpful users of this site) for NHibernate is:我为 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>();

But that doesn't parse well, complaining that the aliases for the joined tables are null references.但这并不能很好地解析,抱怨连接表的别名是空引用。 MyDTO is a custom type for the output: 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; }
}

I'm out of ideas, and while doing this by direct SQL query is possible, I'd like to do it properly, without defeating the purpose of using an ORM.我没有想法,虽然可以通过直接 SQL 查询来做到这一点,但我想正确地做到这一点,而不会违背使用 ORM 的目的。

Thanks in advance!提前致谢!

EDIT:编辑:

The database looks like this: http://i41.tinypic.com/5agciu.jpg (Can't post images yet.)数据库如下所示: http : //i41.tinypic.com/5agciu.jpg (还不能发布图片。)

When I want a HQL query to return a custom type, like you do, I always do it like this:当我希望 HQL 查询返回自定义类型时,就像您一样,我总是这样做:

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

I would have to check some code of mine, but I think that I don't even use the AliasToBeenTransformer in such cases.我将不得不检查我的一些代码,但我认为在这种情况下我什至不使用 AliasToBeenTransformer。 I don't know by heart, since I mostly use NHibernate's ICriteria API (and when using this one, you indeed need to specify the resulttransformer when executing such kind of operation).我不太清楚,因为我主要使用 NHibernate 的 ICriteria API(并且在使用这个 API 时,您确实需要在执行此类操作时指定 resulttransformer)。

NB: I find it weird (or rather awkward) to see underscores in property-names ...注意:我觉得在属性名称中看到下划线很奇怪(或相当尴尬)......

HQL is a query on your objects, not your tables! HQL 是对您的对象的查询,而不是您的表!

In your HQL I see a join between the class tp and a property of that class, tp.Thread_.在您的 HQL 中,我看到类 tp 和该类的属性 tp.Thread_ 之间的连接。 You should distinguish between SQL and HQL there.您应该在那里区分 SQL 和 HQL。 Think of HQL as a query on the object TP instead of on the underlying table structure.将 HQL 视为对对象 TP 而非底层表结构的查询。 Can you post your domain model (the relations between your objects) so that we can help you out?你能发布你的领域模型(你的对象之间的关系)以便我们可以帮助你吗?

Thanks for that picture.谢谢你的那张照片。 However: it looks like your objects are a copy of your tables and I do not think that is what you had in mind?但是:看起来您的对象是您的表格的副本,我认为这不是您的想法? For example: I would have thought that the many-to-many relation between threads and posts would have been mapped using Hibernate.例如:我会认为线程和帖子之间的多对多关系会使用 Hibernate 进行映射。 If that would be the case, you could join threads with posts without having to bother with the intermediate object threadpost, which, in fact, is just holding the relationship between those objects, right?如果是这种情况,您可以将线程与帖子连接起来,而不必费心处理中间对象 threadpost,实际上,它只是保存这些对象之间的关系,对吗?

In other words;换句话说; decorate your thread object with a list of posts, and decorate the post object with a list of threads.用帖子列表装饰您的线程对象,并用线程列表装饰帖子对象。

[decorate] That is to put a list of threads as a property on your post class, and put a list of posts as a property on your threads class. [装饰] 即把一个帖子列表作为一个属性放在你的帖子类上,把一个帖子列表作为一个属性放在你的帖子类上。 What you are looking for is the many-to-many relationship for nhibernate mapping files.您正在寻找的是 nhibernate 映射文件的多对多关系。 That means you do not need to map the many-to-many table in a class, only map the relationship of the post and thread classes.这意味着你不需要映射一个类中的多对多表,只需要映射 post 和 thread 类的关系。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM