【问题标题】:Automatic join with NHibernate / Many-to-one / HQL使用 NHibernate / 多对一 / HQL 自动加入
【发布时间】:2010-07-21 09:26:30
【问题描述】:

我正在开发一个 .NET C# 项目,在该项目上我必须使用 NHibernate 映射属性将我的对象映射到我的数据库中的表。

现在让我们解释一下我的问题是什么。

我有两个映射类,例如 ClassA 和 ClassB。在我的数据库中,表 A 包含一个引用表 B 主键的外键。因此,我向 ClassA 添加了一个以多对一方式映射的 ClassB 实例:

private ClassB b;
[ManyToOne(0, Name = "B", Column = "ID_TABLE_B_TABLE_A", Class = "ClassB", Update = false, Insert = false)]
public virtual ClassB B 
{ 
    get { return b; } 
    set { b= value; } 
}

现在,我想在访问 ClassA 时检查 ClassB 字段的值。我用 HQL 编写查询:

Session.CreateQuery("select a.Id from ClassA a where a.ClassB.Name = 'xxx' ");

这是生成的 SQL:

select tablea0_.ID_TABLE_A as col_0_0_ 
from TABLE_A tablea0_, TABLE_B tableb1_
where tablea0_.ID_TABLE_B_TABLE_A = tableb1_.ID_TABLE_B 
and tableb1_.NAME_TABLE_B='xxx'

我认为这种 HQL 查询应该生成一个 join 语句而不是 where 语句,因为我已经定义了两个类之间的多对一关联。像这样的东西会更好:

select tablea0_.ID_TABLE_A as col_0_0_ 
from TABLE_A tablea0_ 
left join TABLE_B tableb1_ on tableb1_.ID_TABLE_B = tablea0_.ID_TABLE_B_TABLE_A 
where tableb1_.NAME_TABLE_B='xxx'

在我看来,join 看起来更干净。我想知道是否有一种方法可以相应地设置 NHibernate 的行为,而无需在 HQL 查询中明确指定连接语句。

任何帮助将不胜感激!

【问题讨论】:

  • 什么版本的 NHibernate 和你使用什么数据库?
  • 我正在使用 NHibernate 2.1.2 版、.Net Framework 3.5 版和 Oracle 11g。

标签: c# .net nhibernate hql


【解决方案1】:

连接的工作方式如下:

Session.CreateQuery("select a.Id from ClassA a join a.ClassB b where b.Name = 'xxx' ");
Session.CreateQuery("select a.Id from ClassA a left join a.ClassB b where b.Name = 'xxx' ");
Session.CreateQuery("select a.Id from ClassA a left outer join a.ClassB b where b.Name = 'xxx' ");

当然,现在由您来确定哪种连接最适合您。 :)

更多信息@http://docs.jboss.org/hibernate/stable/core/reference/en/html/queryhql.html#queryhql-joins

顺便说一句,如果你想成为一个很酷的孩子,你总是可以使用 Linq to NHibernate:

var result = Session.Linq<ClassA>().Where(a => a.B.Name == 'xxx').ToList();

会生成一个内连接查询。

【讨论】:

  • @Jamie Ide:他使用的是 11g,所以只需进行适当的连接,而不是使用 where 子句。我个人使用 10g,NHibernate 总是以 ANSI 方式连接。
  • 我使用 HQL 方式。我决定不使用 Linq to NHibernate,因为我的一位同事遇到了性能问题。
【解决方案2】:

自从我使用 NHibernate 以来已经有一段时间了,但我认为你不能强迫它这样做。

您可以尝试在多对一映射中指定“fetch=join”,但如果有记忆,这只会改变 NHibernate 在获取相关实体时使用的一般策略,而不是它如何将自定义 HQL 查询转换为 SQL .

但是为什么还要担心呢? 在 99% 的情况下,我实际上查看了生成的 SQL,是因为生成了不正确的 SQL(通常是因为 犯了错误),或者是为了调查性能问题。

【讨论】:

  • SQL 不正确,嗯.. 这可不酷,因为我使用了很多由日志生成的 SQL。
【解决方案3】:

生成的 SQL 取决于数据库方言。 Oracle 直到 9i 才支持 ANSI 连接语法,因此 NHibernate 中的 Oracle 方言可能仍然使用旧语法进行内部连接。左连接产生什么 SQL?如果是tablea0_.ID_TABLE_B_TABLE_A += tableb1_.ID_TABLE_B,那么它也使用旧语法。

【讨论】:

  • 这很奇怪。一直听说用 join 子句比较干净。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-18
  • 2012-03-03
  • 1970-01-01
  • 2013-08-10
  • 2014-07-23
  • 1970-01-01
  • 2015-01-05
相关资源
最近更新 更多