У меня есть такая строка
// $repository is my repository for location data
$locationObject = $repository->findOneBy(array('name' => $locationName));
Которая выбирает первую запись, которую она может найти в таблице Locations
. Это справедливо.
Однако у меня есть некоторые дополнительные данные в этой таблице, чтобы сделать запрос более точным. В частности, столбец "item_name". В классе Location указывается как таковой:
/**
* @ORM\ManyToOne(targetEntity="Item", inversedBy="locations", cascade={"persist", "remove"})
* @ORM\JoinColumn(name="item_id", referencedColumnName="item_id", onDelete="CASCADE")
*/
protected $item;
Таким образом, также существует таблица с элементами item_id, item_name и т.д.
Я хочу изменить исходный findOneBy()
чтобы также фильтровать по названию элемента. Поэтому я хочу что-то вроде:
$locationObject = $repository->findOneBy(array('name' => $locationName, 'item' => $itemName));
Но поскольку $item
является объектом класса Locations, а не строкой или идентификатором, очевидно, что это не сработает. Так что я действительно хочу как-то сильно против item-> getName()...
Я не знаю, как это сделать. У кого-нибудь есть предложения?
благодаря
Я думаю, вы должны создать пользовательский запрос с соединением. Лучше вы создадите собственный класс репозитория для этого объекта, а затем создадите в нем собственную сборку запросов.
Сущность:
// src/AppBundle/Entity/Foo.php
/**
* @ORM\Table(name="foo")
* @ORM\Entity(repositoryClass="AppBundle\Repository\FooRepository")
*/
class Foo
{
...
}
Ваш репозиторий:
// src/AppBundle/Repository/FooRepository.php
use Doctrine\ORM\EntityRepository;
class FooRepository extends EntityRepository
{
public function findByYouWant($id)
{
// your query build
}
}
контроллер:
// src/AppBundle/Controller/FooController.php
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class FooController extends Controller
{
public function showAction()
{
// ... your code
$locationObject = $repository->findByYouWant($id);
}
}
Вы должны добавить метод в свой класс репозитория местоположения и создать запрос, аналогичный следующему:
class LocationRepository extends EntityRepository
{
public function findLocationByItemName($locationName, $itemName)
{
$qb = $this->createQueryBuilder('location');
$qb->select('location')
->innerJoin(
'MyBundle:Item',
'item',
Query\Expr\Join::WITH,
$qb->expr()->eq('location.item', 'item.item_id')
)
->where($qb->expr()->like('location.name', ':locationName'))
->andWhere($qb->expr()->like('item.name', ':itemName'))
->setParameter('locationName', $locationName)
->setParameter('itemName', $itemName);
$query = $qb->getQuery();
return $query->getResult();
}
}
Это так же просто:
$locationObject = $repository->findOneBy(array(
'name' => $locationName,
'item' => $itemObject
));
Используя Doctrine2 для того, чтобы сделать findBy в соответствующем поле объекта, вы должны предоставить экземпляр объекта: $itemObject
.
Вы должны использовать пользовательский dql.You можете построить его с помощью querybuilder.
//in your controller
protected function getEntities($itemName){
$em = $this->get('doctrine.orm.default_entity_manager');
$qb = $em->createQueryBuilder();
$qb->select('a')->from('YourBundleAlias:YourEntityName', 'a')->join('a.item','b')->where('b.item = :item')->setParameter('item', $itemName);
return $qb->getQuery()->execute();
}