symfony - Symfony Doctrine oneToMany 逆数组键
问题描述
(抱歉标题混乱,我很难用一句话解释清楚!)
我基本上有 3 个相互连接的实体SlideshowSlide
:SlideshowContent
和Language
. SlideshowContent
具有以下要链接到的属性SlideshowSlide
:
/**
* @ORM\ManyToOne(targetEntity="App\Entity\SlideshowSlide", inversedBy="content", fetch="EAGER")
* @ORM\JoinColumn(referencedColumnName="id", nullable=false)
*/
private $slide;
以及将其链接到的以下属性Language
:
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Language", fetch="EAGER")
* @ORM\JoinColumn(nullable=false)
*/
private $language;
在我的SlideshowSlide
我有以下content
属性:
/**
* @ORM\OneToMany(targetEntity="App\Entity\SlideshowContent", mappedBy="slide", fetch="EAGER")
*/
private $content;
问题是,我知道我可以获取SlideshowContent
a 中的所有实例SlideshowSlide
,转储类似于:
array:1 [▼
0 => SlideshowSlide {#1052 ▼
-id: 1
-image: null
-imageAlt: null
-url: null
-owner: Domain {#736 ▶}
-content: PersistentCollection {#1077 ▼
-snapshot: array:1 [ …1]
-owner: SlideshowSlide {#1052}
-association: array:16 [ …16]
-em: EntityManager {#381 …11}
-backRefFieldName: "slide"
-typeClass: ClassMetadata {#929 …}
-isDirty: false
#collection: ArrayCollection {#1050 ▼
-elements: array:1 [▼
0 => SlideshowContent {#1094 ▼
-id: 1
-slide: SlideshowSlide {#1052}
-language: Language {#1039 ▶}
-title: "test"
-content: "test2"
}
]
}
#initialized: true
}
}
]
该#collection
数组有一个带有从零开始的索引键的数组。但是,我不想使用id
列language
作为我的键,我该如何实现呢?
解决方案
我刚刚测试了indexed associations,我认为它确实符合您的要求。
这是我的代码和生成的转储:
class A
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @var B
* @ORM\ManyToOne(targetEntity="App\Entity\B", inversedBy="as")
* @ORM\JoinColumn(name="b_id", referencedColumnName="id", nullable=false)
*/
private $b;
/**
* @var C
* @ORM\ManyToOne(targetEntity="App\Entity\C", fetch="EAGER")
* @ORM\JoinColumn(name="c_id", referencedColumnName="id", nullable=false)
*/
private $c;
//...
class B
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @var ArrayCollection<A>
* @ORM\OneToMany(targetEntity="App\Entity\A", mappedBy="b", fetch="EAGER", indexBy="c_id")
*/
private $as;
//...
注意关联indexBy
上的选项。@OneToMany
class C
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
}
数据:
Table A
╔════╦══════╦══════╗
║ id ║ b_id ║ c_id ║
╠════╬══════╬══════╣
║ 34 ║ 12 ║ 2 ║
║ 35 ║ 12 ║ 5 ║
║ 36 ║ 12 ║ 6 ║
║ 37 ║ 12 ║ 1 ║
║ 38 ║ 12 ║ 5 ║
╚════╩══════╩══════╝
转储 B 的实例id = 12
:
B {#691 ▼
-id: 12
-as: PersistentCollection {#641 ▼
// ...irrelevant metadata...
#collection: ArrayCollection {#584 ▼
-elements: array:4 [▼
2 => A {#552 ▼
-id: 34
-b: B {#586}
-c: C {#542 ▼
+__isInitialized__: true
-id: 2
…2
}
}
5 => A {#541 ▼
-id: 38
-b: B {#586}
-c: C {#540 ▼
+__isInitialized__: true
-id: 5
…2
}
}
6 => A {#539 ▶}
1 => A {#537 ▶}
]
没有indexBy
:
B {#566 ▼
-id: 12
-as: PersistentCollection {#516 ▼
// ...irrelevant metadata...
#collection: ArrayCollection {#584 ▼
-elements: array:5 [▼
0 => A {#552 ▼
-id: 34
-b: B {#586}
-c: C {#542 ▼
+__isInitialized__: true
-id: 2
…2
}
}
1 => A {#541 ▼
-id: 35
-b: B {#586}
-c: C {#540 ▼
+__isInitialized__: true
-id: 5
…2
}
}
2 => A {#539 ▶}
3 => A {#537 ▶}
4 => A {#523 ▶}
]
请注意此功能的记录缺点:
- 如果要按字段值更改索引,则必须同时管理键和字段。
- 在每个请求中,键都是从字段值中重新生成的,而不是从之前的集合键中重新生成的。
- 在持久化期间从不考虑 Index-By 键的值。它们仅用于访问目的。
- 用于按特征索引的字段在数据库中必须是唯一的。具有相同索引字段值的多个实体的行为未定义。
我必须强调最后一点:在我的测试中,使用非唯一值作为索引会导致 Doctrine 仅加载该键的最后一个对象。在我的示例中,id 为 35 的对象 A 在c_id
用作索引时被丢弃。
推荐阅读
- java - 如何在构建时从 .class 文件中的 gradle.properties 获取值
- c - 带有 WSL 的 NCurses 不正确地显示框
- .net - Microsoft.Scripting.ArgumentTypeException:预期填充,得到填充
- python - centos安装python3.7时出现的问题
- python - Pyserial 正在从 arduino 获取不一致的数据
- linux - 将目录更改为尾部结果路径的 shell 脚本
- google-pagespeed - 审计和谷歌速度测试的统计数据差异
- tensorflow - 使用 GPU 功能在 tensorflow-hub 上使用 retrain.py 重新训练图像
- gcc - 如果从节中删除 NOLOAD,则从 elf 文件生成的二进制文件会爆炸
- python - pip install -e 选项需要 1 个参数