[英]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.