Php 如何为关联/外键设置ResultsMapping[为什么本机查询返回的关联总是空的]
有关结果映射的更新问题,请参见结尾处的编辑 我定义了两个实体Item和ItemType,其中一个与另一个有多个关联。由于生成和查找正确项的复杂性,我有很多本机查询。这些查询始终返回第一个实体SELECT项的所有列。* 我发现我的关联在第一项上总是空的,我不确定我做错了什么。任何帮助都将不胜感激 实体: 项目类型 查询由MyItemRepository类的getItem方法生成。这有点长,但归结为一个选择项。*从项。。。通过getEntityManager->createNativeQuery$sql、$rsm运行查询 项目类型数据Php 如何为关联/外键设置ResultsMapping[为什么本机查询返回的关联总是空的],php,doctrine,symfony,Php,Doctrine,Symfony,有关结果映射的更新问题,请参见结尾处的编辑 我定义了两个实体Item和ItemType,其中一个与另一个有多个关联。由于生成和查找正确项的复杂性,我有很多本机查询。这些查询始终返回第一个实体SELECT项的所有列。* 我发现我的关联在第一项上总是空的,我不确定我做错了什么。任何帮助都将不胜感激 实体: 项目类型 查询由MyItemRepository类的getItem方法生成。这有点长,但归结为一个选择项。*从项。。。通过getEntityManager->createNativeQuery
id account_id name plural_name label plural_label are_users own_users
31 1 task tasks Task Tasks 1 0
项目数据
id account_id item_type_id field_count ver title
23 1 31 4 1451940837 New Item
我想我已经把范围缩小到了ResultsMapping配置。更新了上面的代码。结果现在返回两个不同的对象,但不会将它们连接起来。项的itemType仍然为null:
object(AppBundle\Entity\Item)[560]
private 'id' => int 23
private 'accountId' => int 1
private 'itemType' => null
private 'fieldCount' => int 4
private 'ver' => int 1451940837
private 'title' => string 'New Item' (length=8)
protected 'fields' =>
array (size=0)
empty
protected 'itemValues' =>
array (size=0)
empty
protected 'cacheValues' =>
array (size=0)
empty
protected 'logger' => null
protected 'itemsRepository' => null
protected 'itemValuesRepository' => null
protected 'fieldsRepository' => null
protected 'loaded' => boolean false
protected 'changeCount' => int 0
object(AppBundle\Entity\ItemType)[507]
private 'id' => int 31
private 'accountId' => int 1
private 'name' => string 'task' (length=4)
private 'pluralName' => string 'tasks' (length=5)
private 'label' => string 'Task' (length=4)
private 'pluralLabel' => string 'Tasks' (length=5)
private 'areUsers' => boolean true
private 'ownUsers' => boolean false
所以现在的问题基本上是:
如何设置ResultsMapping,使其返回一个实体,且所有联接关联保持不变?这是因为您仅从表项中选择。*条令使用延迟加载,不从联接表中的任何数据加载 输入“选择所有要获取的数据”,即:
SELECT items.*, item_types.* ...
信条有一些很好的见解,它很清楚你的错误是什么。对您现有帖子的简短回答是,您应该为ItemType实体使用addJoinedEntityResult而不是addEntityResult
各国:
实体结果描述在转换结果中显示为根元素的实体类型
这意味着,如果在同一映射中添加两个实体结果,您将获得当前看到的结果-Item和ItemType都作为两个不同的对象返回。但是,您知道这两者是相关的,因此a更有意义:
关联实体结果描述一种实体类型,该实体类型在转换结果中显示为关联关系元素,并附加到根实体结果
要直接按原样修复代码,您需要进行更改
$rsm->addEntityResult('\AppBundle\Entity\ItemType', 'item_types');
为此:
$rsm->addJoinedEntityResult(
'\AppBundle\Entity\ItemType',
'item_types',
'items',
'itemType'
);
格式为addJoinedEntityResult$class、$alias、$parentAlias、$relation,因此您可以看到添加的指向父别名的第3个和第4个参数,以及项目类中指向ItemType的字段
总而言之,我认为这太复杂了,可以通过使用。这可以自动将字段映射到对应的SQL列,然后如果您更改了字段的名称或数据库中的列的名称,就不必在映射中更新所有代码
因此,您不必调用复杂的StandardResultsMapping函数,只需执行以下操作:
$rsm = new ResultSetMappingBuilder($this->_em);
$rsm->addRootEntityFromClassMetadata('AppBundle\Entity\Item', 'items');
$rsm->addJoinedEntityFromClassMetadata('AppBundle\Entity\ItemType', 'item_types', 'items', 'itemType',
['id' => 'item_type_id',
'account_id' => 'item_type_id',
'name' => 'item_type_name',
'plural_name' => 'item_type_plural_name',
'label' => 'item_type_label',
'plural_label' => 'item_type_plural_label',
'are_users' => 'item_type_are_users',
'own_users' => 'item_type_own_users']
);
这样,您就消除了冗余代码,使其更不容易出错,更易于测试,并自动处理对实体和数据库的更新。第二个调用显示,您仍然可以传递一个重命名列数组。如果删除项目实体上$itemType上的额外\u LAZY,会发生什么情况?同样的结果,我添加了该选项以使其正常工作。只是删除了它,所以它更清晰了一点,谢谢你指出它。你试过@ORM\ManyToOnetargetEntity=ItemType,fetch=Earge吗?fetch=Earge没有任何效果问题是你想要一个数组$itemObj,$itemObjType??但是如果你的$itemObjType包含一个重复它的id,你就不能这样做。如果你发现数组$itemObjJ、$itemObjType、$itemObjJ比数组$itemObjJ、$itemObjType、数组$itemObjJ、$itemObjSameType更快,那么延迟加载怎么能正常工作呢?事实上,我希望延迟加载能够工作,因为并非所有请求都需要每个嵌套对象,而且在真实完整的实体图中有很多嵌套对象。通过$result[0]->getItemType访问列是否不正确?虽然我不想这样解决它,但我确实尝试添加了它,但它不起作用。该字段仍然为空。问题中的代码已随我的尝试而更新。我在ResultsMapping中添加了相关的entityResult和字段,并将生成该字段的方法也放在了问题中。这几乎就是答案,但是因为默认情况下所有表至少都有相同的id列,所以我必须使用第4个参数将其映射到addJuinedEntityFromClassMetadata。实际上,所有字段几乎都必须重命名,因为许多字段重叠,我更喜欢一致性。我用上面代码的最终版本更新了您的答案的最后一个代码片段。很高兴它成功了。我批准了您的编辑,并做了一些小调整,以提供有关重命名列的第5个参数的更多信息。
SELECT items.*, item_types.* ...
$rsm->addEntityResult('\AppBundle\Entity\ItemType', 'item_types');
$rsm->addJoinedEntityResult(
'\AppBundle\Entity\ItemType',
'item_types',
'items',
'itemType'
);
$rsm = new ResultSetMappingBuilder($this->_em);
$rsm->addRootEntityFromClassMetadata('AppBundle\Entity\Item', 'items');
$rsm->addJoinedEntityFromClassMetadata('AppBundle\Entity\ItemType', 'item_types', 'items', 'itemType',
['id' => 'item_type_id',
'account_id' => 'item_type_id',
'name' => 'item_type_name',
'plural_name' => 'item_type_plural_name',
'label' => 'item_type_label',
'plural_label' => 'item_type_plural_label',
'are_users' => 'item_type_are_users',
'own_users' => 'item_type_own_users']
);