繁体   English   中英

自动加入NHibernate /多对一/ HQL

[英]Automatic join with NHibernate / Many-to-one / HQL

我正在开发一个.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查询中明确指定join语句。

任何帮助,将不胜感激 !

联接的工作方式如下:

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进行NHibernate:

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

将生成一个内部联接查询。

自从我与NHibernate合作以来已经有一段时间了,但是我认为您不能强迫它这样做。

您可以尝试在多对一映射中指定“ fetch = join”,但是如果有内存,这只会更改NHibernate在获取相关实体时通常采用的策略,而不是更改将自定义HQL查询转换为SQL的方式。

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

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

暂无
暂无

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

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