Join 带连接的条令查询生成器嵌套orX和andX条件
我有两个实体Join 带连接的条令查询生成器嵌套orX和andX条件,join,doctrine,repository,conditional-statements,query-builder,Join,Doctrine,Repository,Conditional Statements,Query Builder,我有两个实体User和CalendarEvent。“我的用户”附加到工厂,calendarEvent可用于了解用户是否“借用”到他所属工厂的其他工厂 我的两个实体如下所示: 用户: class User extends BaseUser { /** * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") */ protected $id;
User
和CalendarEvent
。“我的用户”附加到工厂,calendarEvent可用于了解用户是否“借用”到他所属工厂的其他工厂
我的两个实体如下所示:
用户:
class User extends BaseUser
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var string
* @ORM\Column(name="firstname", type="string", length=255, nullable=true)
*/
private $firstname;
/**
* @var string
* @ORM\Column(name="lastname", type="string", length=255, nullable=true)
*/
private $lastname;
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\CalendarEvent", mappedBy="user")
*/
private $events;
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Factory", inversedBy="users")
* @ORM\JoinColumn(name="factory_id", referencedColumnName="id")
*/
private $factory;
}
日历事件:
class CalendarEvent
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var \DateTime
* @ORM\Column(type="datetime", name="event_start")
*/
private $startDate;
/**
* @var \DateTime
* @ORM\Column(type="datetime", name="event_end")
*/
private $endDate;
/**
* @var bool
* @ORM\Column(name="isLoan", type="boolean")
*/
private $isLoan = TRUE;
/**
* @ORM\ManyToOne(targetEntity="Factory")
* @ORM\JoinColumn(name="factory_id", referencedColumnName="id", nullable = true)
*/
private $factory;
/**
* @ORM\ManyToOne(targetEntity="UserBundle\Entity\User", inversedBy="events")
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $user;
}
我想做的是在UserRepository
中创建一个repository函数,当我用factory in entry参数触发请求时,它会让我知道实际是工厂的人
为了实现这一点,我尝试指定一个条件。这种情况应该是这样的:
select * from user where (
(user.factory == $idfactory AND not loaned_to_other_factory) OR
(user.factory != $idfactory AND loaned_to_my_factory)
)
要知道用户是否已被租借到我的工厂,必须验证以下条件:
Does a record exist in CalendarEvent where startDate < NOW and endDate > NOW and loaned == true and factory == $factory
我真的希望我说的有道理,有人能给我一些实现这一点的建议。提前感谢我想您可以将现有查询转换为not in
$notLoanedToOther = $this->createQueryBuilder("e")
->select("e.user")
->from("CalendarEvent","e")
->andWhere('e.startDate < :now')
->andWhere('e.endDate > :now')
->getDQL();
$loanedToMyFactory = $this->createQueryBuilder("e")
->select("e.user")
->from("CalendarEvent","e")
->where('e.factory = :idf')
->andWhere('e.startDate < :now')
->andWhere('e.endDate > :now')
->getDQL();
$qb = $this->_em->createQueryBuilder();
$qb->select('u')
->from($this->_entityName, 'u')
->where(
$qb->expr()->not(
$qb->expr()->in(
'u.id',
$notLoanedToOther
)
)
)
->andWhere(
$qb->expr()->in(
'u.id',
$loanedToMyFactory
)
)
->where(
$qb->expr()->orX(
$qb->expr()->andX(
$qb->expr()->eq('u.factory', ':idf'),
$qb->expr()->not(
$qb->expr()->in(
'u.id',
$notLoanedToOther
)
)
),
$qb->expr()->andX(
$qb->expr()->neq('u.factory', ':idf'),
$qb->expr()->in(
'u.id',
$loanedToMyFactory
)
)
)
)
->setParameter('idf', $idFactory)
->setParameter('now', $someDate)
;
$notloadetoother=$this->createQueryBuilder(“e”)
->选择(“电子用户”)
->来自(“日历事件”、“e”)
->andWhere('e.startDate<:now')
->andWhere('e.endDate>:now')
->getDQL();
$loanedToMyFactory=$this->createQueryBuilder(“e”)
->选择(“电子用户”)
->来自(“日历事件”、“e”)
->其中('e.factory=:idf')
->andWhere('e.startDate<:now')
->andWhere('e.endDate>:now')
->getDQL();
$qb=$this->_em->createQueryBuilder();
$qb->选择('u')
->from($this->\u entityName,'u')
->在哪里(
$qb->expr()->非(
$qb->expr()->in(
“u.id”,
$notloanedother
)
)
)
->在哪里(
$qb->expr()->in(
“u.id”,
$loanedToMyFactory
)
)
->在哪里(
$qb->expr()->orX(
$qb->expr()->andX(
$qb->expr()->eq('u.factory',':idf'),
$qb->expr()->非(
$qb->expr()->in(
“u.id”,
$notloanedother
)
)
),
$qb->expr()->andX(
$qb->expr()->neq('u.factory',':idf'),
$qb->expr()->in(
“u.id”,
$loanedToMyFactory
)
)
)
)
->setParameter('idf',$idFactory)
->setParameter('now',$someDate)
;
根据您在SQL中指定的条件,使用带有联接的简单DQL查询,而不是复杂的not in子句,怎么样 从用户位置选择*( (user.factory==$idfactory且未贷给其他工厂)或 (user.factory!=$idfactory并借给我的工厂) ) 您可以用DQL编写它的等价物,如下所示
SELECT u
FROM User u
LEFT JOIN u.events nl WITH e.startDate < :now AND e.endDate > :now
LEFT JOIN u.events l WITH e.startDate < :now AND e.endDate > :now AND e.factory = :idf
WHERE (
u.factory = :idf AND nl.id IS NULL
) OR (
u.factory != :idf AND l.id IS NOT NULL
)
选择u
来自用户u
左键使用e.startDate<:now和e.endDate>立即加入u.events nl
左键使用e.startDate<:now和e.endDate>:now和e.factory=:idf连接u.events l
在哪里(
u、 factory=:idf和nl.id为NULL
)或(
u、 工厂!=:idf和l.id不为空
)
使用附加子句将事件实体与用户连接两次,一个用于loaned,另一个用于not loaded,然后应用您的条件,我添加了IS NULL
和IS not NULL
过滤器以满足您的exists和not exists条件
SELECT u
FROM User u
LEFT JOIN u.events nl WITH e.startDate < :now AND e.endDate > :now
LEFT JOIN u.events l WITH e.startDate < :now AND e.endDate > :now AND e.factory = :idf
WHERE (
u.factory = :idf AND nl.id IS NULL
) OR (
u.factory != :idf AND l.id IS NOT NULL
)