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
+
0
-

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
+
0
-

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)

Btw, dědit DAO/Repository je zlo

mbskot
Člen | 42
+
0
-

hell :D taká banálna chyba. Ďakujem už to funguje správne :)