为什么 NHibernate 从一个数据库行返回多个结果?

发布于 2024-10-02 07:31:06 字数 2935 浏览 0 评论 0原文

我的翻译引擎映射如下:

<class name="Core.Model.Entities.Translation, Core.Model" table="translation" lazy="false">
<id name="Id" column="id" type="Int64">
  <generator class="native" />
</id>
<map name="Translations" table="translation_value" inverse="true" fetch="join" cascade="all-delete-orphan" lazy="false">
  <key column="translation_id" />
  <index-many-to-many column="language_id" class="Core.Model.Entities.Language, Core.Model"/>
  <one-to-many class="Core.Model.Entities.TranslationValue, Core.Model"/>
</map>
</class>


<class name="Core.Model.Entities.TranslationValue, Core.Model" table="translation_value" lazy="false">
<id name="Id" column="id" type="Int64">
  <generator class="native" />
</id>
<property name="Value" column="value" type="String"/>
<many-to-one name="Translation" column="translation_id" class="Core.Model.Entities.Translation, Core" not-null="true"/>
<many-to-one name="Language" column="language_id" class="Core.Model.Entities.Language, Core" not-null="true" />

示例“item”类使用这样的翻译:

<class name="Core.Model.Entities.Item, Core.Model" table="item" lazy="true">
    <id name="Id" column="id" type="long">
        <generator class="native" />
    </id>
    <property name="Symbol" column="symbol"/>
    <many-to-one name="Name" class="Core.Model.Entities.Translation, Core.Model" fetch="join" column="name" cascade="all" />
    <many-to-one name="Description" class="Core.Model.Entities.Translation, Core.Model"  fetch="join" column="description" cascade="all" /> 
</class>

它工作得很好,但是当单个项目有多个翻译时,Item.Dao.GetAll() 方法会返回与翻译一样多的结果,所以如果我向 Item 添加 3 个翻译。名称,Item.Dao.GetAll 方法返回 3 个相同的项目对象。我已经检查了数据库 - 一切都很好 - “item”表中的一行,“translation”表中的一行和“translation_value”表中的三行。当数据库中只有 1 个条目时,为什么 Nhibernate 返回 3 个结果!?

编辑: 我查找了 NHibernate 生成的查询,看起来像这样:

SELECT 
this_.id as id23_3_, 
this_.symbol as symbol23_3_, 
this_.name as name23_3_, 
this_.description as descript4_23_3_, 
this_.sort as sort23_3_, 
this_.published as published23_3_, 
this_.created_at as created7_23_3_, 
this_.updated_at as updated8_23_3_, 
translatio2_.id as id26_0_, 
translatio3_.translation_id as translat3_5_, 
translatio3_.id as id5_, 
translatio3_.language_id as language4_5_, 
translatio3_.id as id9_1_, 
translatio3_.value as value9_1_, 
translatio3_.translation_id as translat3_9_1_, 
translatio3_.language_id as language4_9_1_, 
translatio4_.id as id26_2_ FROM item this_ 

left outer join translation translatio2_ on this_.name=translatio2_.id 
left outer join translation_value translatio3_ on translatio2_.id=translatio3_.translation_id 
left outer join translation translatio4_ on this_.description=translatio4_.id

该查询返回 3 个结果,每个翻译一个。但是为什么 nhibernate 不填充多对一翻译对象而不是返回三行?

I have translation engine mapped as follows:

<class name="Core.Model.Entities.Translation, Core.Model" table="translation" lazy="false">
<id name="Id" column="id" type="Int64">
  <generator class="native" />
</id>
<map name="Translations" table="translation_value" inverse="true" fetch="join" cascade="all-delete-orphan" lazy="false">
  <key column="translation_id" />
  <index-many-to-many column="language_id" class="Core.Model.Entities.Language, Core.Model"/>
  <one-to-many class="Core.Model.Entities.TranslationValue, Core.Model"/>
</map>
</class>


<class name="Core.Model.Entities.TranslationValue, Core.Model" table="translation_value" lazy="false">
<id name="Id" column="id" type="Int64">
  <generator class="native" />
</id>
<property name="Value" column="value" type="String"/>
<many-to-one name="Translation" column="translation_id" class="Core.Model.Entities.Translation, Core" not-null="true"/>
<many-to-one name="Language" column="language_id" class="Core.Model.Entities.Language, Core" not-null="true" />

Example "item" class uses that translations like that:

<class name="Core.Model.Entities.Item, Core.Model" table="item" lazy="true">
    <id name="Id" column="id" type="long">
        <generator class="native" />
    </id>
    <property name="Symbol" column="symbol"/>
    <many-to-one name="Name" class="Core.Model.Entities.Translation, Core.Model" fetch="join" column="name" cascade="all" />
    <many-to-one name="Description" class="Core.Model.Entities.Translation, Core.Model"  fetch="join" column="description" cascade="all" /> 
</class>

It works great, BUT when single item has multiple translations, Item.Dao.GetAll() method, returns as many results as there are translations, so if I add 3 translations to Item.Name, Item.Dao.GetAll method returns me 3 identical item objects. I have checked the database - everything is fine - one row in "item" table, one row in "translation" table and three rows in "translation_value" table. Why Nhibernate returns me 3 results when there is only 1 entry in database!?

EDIT:
I Looked up on query wich NHibernate generates and i looks like this:

SELECT 
this_.id as id23_3_, 
this_.symbol as symbol23_3_, 
this_.name as name23_3_, 
this_.description as descript4_23_3_, 
this_.sort as sort23_3_, 
this_.published as published23_3_, 
this_.created_at as created7_23_3_, 
this_.updated_at as updated8_23_3_, 
translatio2_.id as id26_0_, 
translatio3_.translation_id as translat3_5_, 
translatio3_.id as id5_, 
translatio3_.language_id as language4_5_, 
translatio3_.id as id9_1_, 
translatio3_.value as value9_1_, 
translatio3_.translation_id as translat3_9_1_, 
translatio3_.language_id as language4_9_1_, 
translatio4_.id as id26_2_ FROM item this_ 

left outer join translation translatio2_ on this_.name=translatio2_.id 
left outer join translation_value translatio3_ on translatio2_.id=translatio3_.translation_id 
left outer join translation translatio4_ on this_.description=translatio4_.id

This query IS returning 3 results, one for each translation. But why nhibernate does not fills many to one translations objects instead of returning three rows?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

长不大的小祸害 2024-10-09 07:31:06

发生这种情况是因为您在 Translations 集合的映射中指定了 fetch="join"。如果您不想对集合使用延迟加载,那么您应该更改 Dao.GetAll() 方法以使用 HQL 或 Criteria API 来急切地获取集合并将结果限制为不同的父对象。

It's happening because you have specified fetch="join" in the mapping for the Translations collection. If you don't want to use lazy loading for the collection, then you should change your Dao.GetAll() method to use HQL or the Criteria API to eagerly fetch the collection and limit the result to distinct parent objects.

别低头,皇冠会掉 2024-10-09 07:31:06

这取决于 GetAll() 方法的实现方式。如果您使用的是标准 API,请使用

 criteria.SetResultTransformer(new DistinctRootEntityResultTransformer());

HQL 具有不同的子句。

It depends how the GetAll() method is implemented. If you are using criteria API, use

 criteria.SetResultTransformer(new DistinctRootEntityResultTransformer());

HQL has a distinct clause.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文