gpt4 book ai didi

php - 学说 DQL : DQL Join between 4 entities

转载 作者:行者123 更新时间:2023-11-29 17:58:04 24 4
gpt4 key购买 nike

所以,我有这个实体结构:

  • User有一些Email s(同时多个);
  • 每个Email属于Domain s (如果 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如果他有 EmailDomain .

所以,如果User有一个 Email email@example.com,他可以访问Profile Domain的example.com。

我知道我需要加入四个表,但我不知道如何做到这一点 JOIN .

你能帮我吗?

最佳答案

由于您将所有关系设为双向,因此您可以通过连接 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 会将它们折叠为结果集中的单个条目getResultgetArrayResult。如果您使用 getScalarResult as described in the documentation,您将得到重复项.

<小时/>

您也可以反过来执行此操作,将用户中的电子邮件个人资料加入到能够从您的 User 实例获取所有数据。重要的部分是使用 leftJoin 进行 profile 连接,以便仍然选择没有配置文件的域。在这种情况下,您需要向 User 类添加一个方法来抓取用户的电子邮件并检索相应的个人资料。

关于php - 学说 DQL : DQL Join between 4 entities,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48639519/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com