原则ORM:使用接口作为不同实体的关系吗? [英] Doctrine ORM: use interface as relation for different entities?
问题描述
如何在学说中的多对多关系中使用界面?
How to use interface in many-to-many relation in doctrine?
在我的应用中,有3个实体:用户,汽车和驾驶员。用户可以将汽车和驾驶员添加为收藏夹。因此,我做了一个简化的结构:
In my app there is 3 entities: User, Car and Driver. User can add cars and drivers as favorites. So i made this structure (simplified):
具有最喜欢的功能的用户:
User, who has favorite feature:
namespace Acme\AppBundle\Entities;
use Acme\AppBundle\Interfaces\HasFavorites;
/** @ORM\Entity */
class User implements HasFavorites
{
/** @ORM\ManyToMany(targetEntity="Acme\AppBundle\Entities\Favorite") */
protected $favorites;
public function getFavorites() : ArrayCollection
{
return $this->favorites;
}
public function addFavorite(Favorite $favorite)
{
$this->favorites->add($favorite);
}
}
收藏夹对象模型:
namespace Acme\AppBundle\Entities;
use Acme\AppBundle\Interfaces\Favoritable;
/** @ORM\Entity */
class Favorite
{
/** @ORM\ManyToOne(targetEntity="Acme\AppBundle\Entities\User") */
private $owner;
/** @ORM\ManyToOne(targetEntity="Acme\AppBundle\Interfaces\Favoritable") */
private $target;
public function __construct(User $owner, Favoritable $target)
{
$this->owner = $owner;
$this->target = $target;
}
public function getOwner() : User
{
return $this->owner;
}
public function getTarget() : Favoritable
{
return $this->target;
}
}
汽车和驾驶员–可以添加到收藏夹的实体:
Car and Driver – entities that can be added to favorites:
namespace Acme\AppBundle\Entities;
use Acme\AppBundle\Interfaces\Favoritable;
/** @ORM\Entity */
class Car implements Favoritable { /* ... */ }
/** @ORM\Entity */
class Driver implements Favoritable { /* ... */ }
但是当我使用命令 ./ bin / console doctrine:schema:update --force
更新架构时,我会报错
But when i update my schema with command ./bin/console doctrine:schema:update --force
, i'll get error
[Doctrine\Common\Persistence\Mapping\MappingException]
Class 'Acme\AppBundle\Interfaces\Favoritable' does not exist
我测试中的这段代码也可以正常工作(如果我不使用数据库),所以命名空间和文件路径是正确的:
This code in my tests also working ok (if i don't work with database) so namespaces and file paths are correct:
$user = $this->getMockUser();
$car = $this->getMockCar();
$fav = new Favorite($user, $car);
$user->addFavorite($fav);
static::assertCount(1, $user->getFavorites());
static::assertEquals($user, $fav->getUser());
如何建立这种关系?我在搜索中发现的东西只有在逻辑上汽车/驾驶员基本相同的情况下才出现。
How to do this relation? What i've found yet in search that is only situation when Car/Driver are mostly the same by logic.
我在数据库中需要的只是这样的(期望),但并不是那么重要:
What i need in database is just something like this (desired) but it's not so important:
+ ––––––––––––– + + ––––––––––––– + + –––––––––––––––––––––––––––––––––– +
| users | | cars | | favorites |
+ –– + –––––––– + + –– + –––––––– + + –––––––– + ––––––––– + ––––––––––– +
| id | name | | id | name | | owner_id | target_id | target_type |
+ –– + –––––––– + + –– + –––––––– + + –––––––– + ––––––––– + ––––––––––– +
| 42 | John Doe | | 17 | BMW | | 42 | 17 | car |
+ –– + –––––––– + + –– + –––––––– + + –––––––– + ––––––––– + ––––––––––– +
推荐答案
使用Doctrine的 ResolveTargetEntityListener
,您可以按照您的方式注释关系以目标 interface 为目标,然后将其解析为特定的实体。
With Doctrine's ResolveTargetEntityListener
you can annotate a relationship to target interface the way you did, and then resolve it to a specific entity.
更多有关Doctrine文档的信息: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/cookbook/resolve-target-entity-listener.html
More in Doctrine docs: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/cookbook/resolve-target-entity-listener.html
或者在这里,如果您使用的是Symfony框架: http://symfony.com/doc/current/doctrine/resolve_target_entity.html
Or here, if you're using Symfony framework: http://symfony.com/doc/current/doctrine/resolve_target_entity.html
但是,您无法实现自己的目标想要这样-一个接口被分解为多个实现该i的实体接口使用区分符。这不是AFAIK。您只能将一个接口解析为一个实体,以便在一个表中使用。
HOWEVER, you can't achieve what you want with this - one interface being resolved into multiple entities implementing this interface using a "discriminator". That's not possible AFAIK. You can only resolve one interface to one entity for use within one table.
这篇关于原则ORM:使用接口作为不同实体的关系吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!