所以,我有这个实体结构:
User
有一些Email
s(同时超过一个); Email
的每个Domain
(如果是email@example.com,那么我在数据库中有Domain
“example.com`)Domain
都可以与Profile
相关联。 现在,给定User
我想获得他可以访问的所有Profiles
(如果有的话!可能Domain
没有Profile
)。
实体结构:
// User entity
use FOS\UserBundle\Model\User as BaseUser;
/**
* @ORM\Entity
* @ORM\Table(name="users")
*/
class User extends BaseUser
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var ArrayCollection
*
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Email", mappedBy="forUser")
*/
protected $emails;
...
}
// Email entity
/**
* @ORM\Entity(repositoryClass="\AppBundle\Repository\EmailRepository")
* @ORM\Table(name="emails")
*/
class Email
{
/**
* @var EmailValue
*
* @ORM\Id
* @ORM\Column(name="email", type="email", nullable=false, unique=true)
*/
protected $email;
/**
* @var Domain
*
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Domain", inversedBy="emails")
* @ORM\JoinColumn(name="domain", referencedColumnName="second_level")
*/
protected $domain;
/**
* @var \MyNamespace\Bundle\UserBundle\Entity\User
*
* @ORM\ManyToOne(targetEntity="MyNamespace\Bundle\UserBundle\Entity\User", inversedBy="emails")
* @ORM\JoinColumn(name="for_user", referencedColumnName="id")
*/
protected $forUser;
...
}
// Domain entity
/**
* @ORM\Entity(repositoryClass="\AppBundle\Repository\DomainRepository")
* @ORM\Table(name="domains")
*/
class Domain
{
/**
* @var string
*
* @ORM\Id
* @ORM\Column(type="string", nullable=false, unique=true)
*/
private $secondLevel;
/**
* @var UrlValue
*
* @ORM\Column(name="url", type="uri", nullable=false, unique=true)
*/
private $url;
...
/**
* Each Domain can be linked to only one Profile.
*
* @var Profile|null
*
* @ORM\OneToOne(targetEntity="AppBundle\Entity\Profile", inversedBy="domain")
*/
private $profile;
/**
* Each Domain can have more than one Email.
*
* @var Collection
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Email", mappedBy="domain")
*/
private $emails;
...
}
// Profile entity
/**
* @ORM\Table(name="profiles")
* @ORM\Entity(repositoryClass="\AppBundle\Repository\ProfileRepository")
* @ORM\HasLifecycleCallbacks
*/
class Profile
{
/**
* @var int
*
* @ORM\Column(name="id", type="string", unique=true)
* @ORM\Id
* @ORM\GeneratedValue(strategy="CUSTOM")
* @ORM\CustomIdGenerator(class="AppBundle\Doctrine\IdGenerator")
*/
private $id;
/**
* Each Store can have only one Domain.
*
* @var Domain
*
* @ORM\OneToOne(targetEntity="AppBundle\Entity\Domain", mappedBy="profile")
*/
private $domain;
...
}
现在,给定User
我想获得他可以访问的所有Profiles
(如果有的话!可能Domain
没有Profile
)。
我决定User
是否可以访问Profile
Email
Domain
是否User
。
因此,如果Email
有Profile
email@example.com,则他可以访问Domain
example.com的JOIN
。
我知道我需要加入这四张桌子,但我不知道如何才能这样做<div>
..
</div>
。
你能帮助我吗?
答案 0 :(得分:0)
由于您创建了所有关系双向,因此可以通过连接Profile
表中的表来执行此类查询。您可以使用the query builder并将以下方法添加到ProfileRepository
,以便根据User
实例执行搜索:
public function getUserProfiles(User $user)
{
return $this->createQueryBuilder('profile')
->addSelect('domain') // select the corresponding domain at the same time
->join('profile.domain', 'domain')
->join('domain.emails', 'emails')
->where('emails.forUser = :user')
->setParameter('user', $user)
->getQuery()
->getResult();
}
如果您只是可以访问用户ID,则可以使用where('IDENTITY(emails.forUser) = :userId')
代替上面写的where
子句。
注意:如果用户有多个电子邮件链接到同一个域/配置文件,则基础SQL查询将多次返回相同的配置文件条目,但如果您使用,则Doctrine会将它们折叠为结果集中的单个条目getResult
或getArrayResult
。如果您使用getScalarResult
as described in the documentation。
你也可以反过来这样做,加入来自emails
的{{1}},domain
和profile
,以便能够覆盖{{1}的所有数据实例。重要的是将User
用于User
联接,以便仍然可以选择没有配置文件的域。在这种情况下,您需要向leftJoin
类添加一个方法来抓取用户的profile
并检索相应的配置文件。