我有两个实体通过一对多单向链接与连接表关联。
use Doctrine\ORM\Mapping as ORM;
/**
* @Entity(repositoryClass="FooRepository")
*/
class Foo
{
/**
* @var Collection
* @ORM\ManyToMany(targetEntity="Bar")
* @ORM\JoinTable(
* name="foo_bar",
* inverseJoinColumns={@ORM\JoinColumn(unique=true)}
* )
*/
private $bars;
/**
* @var int
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
// [...]
}
/**
* @Entity(repositoryClass="BarRepository")
*/
class Bar
{
/**
* @var int
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
// [...]
}
我想在我的BarRepository
类中使用a foo id和bar id创建一个方法,该方法返回一个或null Bar
个对象。
实际上我的班级看起来像这样:
use Doctrine\ORM\EntityRepository;
class BarRepository extends EntityRepository
{
/**
* Finds a single bar.
* @param int $fooId The foo identifier.
* @param int $barId The bar identifier.
* @return Bar|null
*/
public function findOneByFoo($fooId, $barId)
{
$qb = $this->createQueryBuilder('b');
$qb->innerJoin('Foo', 'f', Expr\Join::WITH, 'f.id = :fooId')
->where('b.id = :barId')
->setParameter('fooId', $fooId)
->setParameter('barId', $barId)
->getQuery()->getOneOrNullResult();
}
}
但即使bar id与foo对象没有关联,这也会返回一个bar对象。
答案 0 :(得分:1)
首先!这不是必需的,但我建议你总是写 注释中的完整映射。
让我们来看看你的实体。我们可以就你的问题做出下一个断言 一对多的:
一个Foo对象可以有很多Bar对象,但每个Bar对象都会引用 只有一个,没有更多的Foo对象。 例如,一个人可以拥有大量的信用卡,但每个信用卡 卡属于一个人。
因此我们可以写下来:
/**
* @Entity(repositoryClass="FooRepository")
*/
class Foo
{
/**
* Unidirectional One-To-Many
* One Foo has many Bar, however Bar has only one Foo
*
* @ORM\ManyToMany(targetEntity="Bar")
* @ORM\JoinTable(
* name="foo_bar_table",
* joinColumns={@JoinColumn(name="foo_id", referencedColumnName="id")},
* inverseJoinColumns={@JoinColumn(name="bar_id", referencedColumnName="id", unique=true)
*/
private $bars;
/**
* Foo constructor
*/
public function __construct()
{
$this->bars = new \Doctrine\Common\Collections\ArrayCollection();
}
当然,您总是会有一个已键入id的条形对象。 为什么?让我们来看看你们的关系(表格)。 Foo - 这是一个具有字段ID的表 吧 - 这是一个表,它有字段ID。 foo_bar_table - 这个表有foo_id,bar_id。
当您进行连接时 - 您只需将另一个表添加到另一个表中。
这些表彼此之间没有关联。所以你想要
酒吧对象 - 你明白了。
您需要从Bar存储库中获取Bar对象。这将是
更好。
答案 1 :(得分:0)
好的,感谢staskrak,我重写了我的"查询"像这样,它工作正常。
Foo
和Bar
个实体是相同的。
我保留了查询的相同基础,但在Foo->bars
属性和Bar
实体之间添加了内部联接。
use Doctrine\ORM\EntityRepository;
class BarRepository extends EntityRepository
{
public function findOneByFoo($fooId, $barId)
{
$parameters = [
':fooId' => $fooId,
':barId' => $barId
];
$qb = $this->createQueryBuilder('b');
return $qb
->innerJoin('Foo', 'f', 'WITH', 'f.id = :fooId')
// below, the added inner join
// it makes the link between the Foo->bars property and the Bar entity
->innerJoin('f.bars', 'fb', 'WITH', 'b.id = fb.id')
->where('b.id = :barId')
->setParameters($parameters)
->getQuery()
->getOneOrNullResult();
}
}