Nhibernate CreateQuery和CreateCriteria生成不同的SQL查询

Nhibernate CreateQuery和CreateCriteria生成不同的SQL查询,nhibernate,fluent-nhibernate,nhibernate-mapping,Nhibernate,Fluent Nhibernate,Nhibernate Mapping,客户端具有报告、配置等属性。每个客户端只能有一个。此外,每个报告只能属于一个客户机。这在某种程度上是一对一的关系。因此,我的报表表有一个foreignkey列clientID。配置表和其他表也是如此 现在,根据我在nhibernate网站上读到的一对一的定义,这意味着Report和Client的主键应该是相同的。让我们假设我不能以这种方式实现它。因此,为了模拟数据库中的结构,我有以下映射: 报告地图 References(x => x.Client, "clientID").Unique(

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

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

报告地图

References(x => x.Client, "clientID").Unique().Not.Nullable();
客户地图

HasOne(x => x.Report).PropertyRef(x => x.Client).LazyLoad().Cascade.SaveUpdate();
现在我面临的问题是,当我查询客户机时,NHibernate也会生成查询以获取报告、配置等。。。此外,根据我使用的是条件还是HQL,生成的查询差别很大

var client = session.CreateQuery("from Client as c where c.Id = :clientId")
                    .SetParameter("clientId", 1L)
                    .UniqueResult<Client>();
或者,员工与个人之间具有唯一约束的外键可以>表示为:


通过向Person>映射添加以下内容,可以实现双向关联:



从技术上来说,据我所知,我没有做错任何事。这个场景应该得到nhibernate的支持

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


如果这更有意义的话,你也可以将它映射到另一个方向,让客户端位于多个方向。

你读过吗?还有我之前读过的Gregory的文章。这不适用于我的情况。第二篇文章更有趣,因为它提到了同样的问题。谢谢你。我留下了一条评论,指向这个问题。希望有人能对这种行为做出恰当的解释。他的解决方案是明确地提到您需要从客户机获得的所有属性。那很不方便。我只是想知道这是否是一个bug,以及如何避免它。关于Gregory的帖子,我将其映射为多对一,并对其施加唯一的约束。为了实现双向性,我在另一端使用HasOne和PropertyRef来进行适当的关联。理想情况下,我希望将报表映射为组件或值对象。但我有一个现有的数据库,我不能改变它。你的建议不错。我实现了它,它似乎按照我想要的方式工作。不过,我仍然希望有一个适当的解决办法。或者至少是对问题的解释。我不知道我是否应该将此发布到nhibernate用户列表。我先在这里等几天。组件用于与包含类型在同一个表中的字段。例如,您可能在Company类上有一个Address组件来映射表中的Street、City和State字段。我认为正确的解决方案是更改映射--您误用了一对一映射,不同的获取策略就是这种结果。关于组件,这就是我的意思。因为我知道一个客户总是只有一个报告,所以从技术上讲,我可以将两个表合并为一个。由于某些原因,我们没有这样做。我猜其中一个原因是Client表最终会有很多很多列。并非所有这些我们总是需要的。像Report这样的东西只在特定的屏幕中需要。不管怎样,正如我所说的,你提出的解决方案效果很好。但我觉得这更多的是一种变通而非解决方案。
* primary key associations
* unique foreign key associations
<many-to-one name="Person" class="Person" column="PERSON_ID" unique="true"/>
<one-to-one name="Employee" class="Employee" property-ref="Person"/>