Doctrine 2 – Asociácia One-To-Many
Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
- mbskot
- Člen | 42
Cafte,
podľa dokumentácie sa snažím vytvoriť jednosmernú asociáciu medzi
„City“ (ONE) a „Alias“ (MANY).
/**
* @ORM\Entity(repositoryClass="App\Feeds\Models\Category\CategoryDao")
* @ORM\Table(name="Category", indexes={@ORM\Index(name="category_idx", columns={"name"})})
*/
class CategoryEntity extends Entity
{
/**
* @ORM\Column(unique=TRUE)
* @var string
*/
private $name;
/**
* @ORM\ManyToMany(targetEntity="App\Feeds\Models\Alias\AliasEntity", cascade="ALL", fetch="EAGER")
* @ORM\JoinTable(
* name="category_aliases",
* joinColumns={@ORM\JoinColumn(name="category_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="alias_id", referencedColumnName="id", unique=true)}
* )
* @var ArrayCollection
*/
private $aliases;
/...
}
/**
* @ORM\Entity
* @ORM\Table(name="Alias", indexes={@ORM\Index(name="alias_idx", columns={"name"})})
*/
class AliasEntity extends Entity
{
/**
* @ORM\Column(unique=TRUE)
* @var string
*/
private $name;
//...
}
class CategoryDao extends Dao
{
/**
* @param array $names
* @return ArrayCollection
*/
public function findByName(array $names)
{
$query = $this->createQueryBuilder();
$result = $query->select('category')
->from($this->getClassName(), 'category', 'category.name')
->leftJoin($this->related('aliases')->getClassName(), 'alias')
->where($query->expr()->orX(
$query->expr()->in('category.name', ':names'),
$query->expr()->in('alias.name', ':names')
))
->setParameter('names', $names)
->getQuery()
->getResult();
return new ArrayCollection($result);
}
}
Select, napísaný v CityDao::findByName generuje DQL:
SELECT category
FROM App\Feeds\Models\Category\CategoryEntity category INDEX BY category.name
LEFT JOIN App\Feeds\Models\Alias\AliasEntity alias
WHERE category.name IN(:names) OR alias.name IN(:names)
a to sa preloží do SQL:
SELECT c0_.name AS name0, c0_.id AS id1
FROM Category c0_
LEFT JOIN Alias a1_ ON (c0_.name IN (?) OR a1_.name IN (?))
Výsledkom je, že mi vždy vráti úplne všetký kategórie (aj keď hľadám len jednu). Prečo?
- Filip Procházka
- Moderator | 4668
Joiny se píší takto
SELECT c
FROM App\Feeds\Models\Category\CategoryEntity c INDEX BY c.name
LEFT JOIN c.aliases a
WHERE c.name IN(:names) OR a.name IN(:names)