CreateQuery和CreateCriteria生成不同的SQL查询

时间:2010-01-13 13:22:07

标签: nhibernate fluent-nhibernate nhibernate-mapping

客户端具有报告,配置等属性。客户端只能有一个。此外,每个报告只能属于一个客户端。这在某种程度上是一对一的关系。因此,我的Report表有一个foreignkey列clientID。配置和其他表相同。

现在根据我在nhibernate网站上读到的一对一定义,这意味着Report和Client的主键都应该是相同的。让我们假设我无法以这种方式实现它。因此,为了模拟我在数据库中的结构,我有以下映射:

ReportMap

References(x => x.Client, "clientID").Unique().Not.Nullable();

ClientMap

HasOne(x => x.Report).PropertyRef(x => x.Client).LazyLoad().Cascade.SaveUpdate();

现在我遇到的问题是,当我查询客户端时,NHibernate也会生成查询以获取报告,配置等...此外,根据我是使用Criteria还是HQL,生成的查询变化很大。

var client = session.CreateQuery("from Client as c where c.Id = :clientId")
                    .SetParameter("clientId", 1L)
                    .UniqueResult<Client>();

为客户端生成一个查询,然后对我映射为HasOne的每个属性进行一次查询。即另外2个查询。一个用于报告,一个用于配置。 HQL总共生成3个查询。

但是,如果我使用加载方法或条件,则会生成一个连接所有相关表的查询

尽管将这些集合映射为延迟加载,为什么NHibernate会获取它们?我真的只想要来自Client表的信息。

对此有合理的解释吗?

从Nhibernate关于获取策略的文档中,我理解单个关联是延迟代理获取的。并且只有在访问关联时才执行select的默认提取策略。就我而言,我没有访问该协会。我只是在阅读属于客户的属性。

这一切都令人困惑......

Edit1 :我已经将我的一对一关系映射到nhibernate文档中。 http://nhibernate.info/doc/nh/en/index.html#mapping-declaration-onetoone

  

有两种一对一的品种   关联:

* primary key associations
* unique foreign key associations
     

或者,具有唯一约束的外键,从Employee到Person,可以是>表达为:

<many-to-one name="Person" class="Person" column="PERSON_ID" unique="true"/>
  

通过将以下内容添加到Person&gt;映射:

,可以使此关联成为双向关联
<one-to-one name="Employee" class="Employee" property-ref="Person"/>

从技术上讲,据我所知,我没有做错任何事。这种情况应该由nhibernate支持。

1 个答案:

答案 0 :(得分:1)

我不确定您的查询有什么问题,但我建议您更改映射。您拥有Client-Report与业务规则之间的一对多关系,客户端只能有一个报表。你应该这样映射它。报告集合可以映射为私有成员,您可以在客户端上公开Report属性以强制执行业务规则。我希望以这种方式映射它将解决您的查询问题。

如果更有意义的话,您也可以在很多方面将客户端映射到另一个方向。