Symfony 获取实体子对象id而不加入或新建sql请求

Symfony 获取实体子对象id而不加入或新建sql请求,symfony,doctrine-orm,doctrine,Symfony,Doctrine Orm,Doctrine,例如,我有一个实体用户,它有一个联系人。如何在不加入联系人表的情况下获取联系人ID $user = $entityManager->userRepository->findUserById(1); $contactId = $user->getContact()->getId(); 调用`getContact()时,将从数据库加载整个联系人。如何避免此SQL请求而不在findUserById中添加联接。我只需要在users表中输入contactId,但没有像$user-

例如,我有一个实体用户,它有一个联系人。如何在不加入联系人表的情况下获取联系人ID

$user = $entityManager->userRepository->findUserById(1);
$contactId = $user->getContact()->getId();

调用`getContact()时,将从数据库加载整个联系人。如何避免此SQL请求而不在findUserById中添加联接。我只需要在users表中输入contactId,但没有像$user->getContactId()这样的简单函数

我建议您更改特定查询中的获取模式,如文档中所述

因此,您可以如下描述您的查询:

// Supposing this method in the repository class
public function findUserById($idUser)
{
$qb =  $this->createQueryBuilder('u')
        ->where("u.id = :idUser")
        ->setParameter("idUser", $idUser);

        $query = $qb->getQuery();
        // Describe here all the entity and the association name that you want to fetch eager
        $query->setFetchMode("YourBundle\\Entity\\Contract", "contract", ClassMetadata::FETCH_EAGER);
        ...

return $qb->->getResult();
}
注意:

在查询过程中更改获取模式仅适用于一对一 以及多对一关系


希望这对你有所帮助看看这篇文章。我在一个manytone关系中测试了一个简单的示例,但相关对象没有加载

您的情况听起来非常适合二级缓存

这样,第一个查询将从数据库中获取,但随后的每个查询都将从第二级缓存中获取,此外,如果您使用条令更改数据,那么缓存将自动更新。因此,我建议您为缓存设置很长的时间。我个人最喜欢的缓存是1个月,大约2592000秒

像这样在用户实体中启用它

<?php
namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\Common\Collections\ArrayCollection;

/**
* @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
* @ORM\Cache(usage="NONSTRICT_READ_WRITE", region="users_region")
* @ORM\Table(
*   name="site_users",
*   indexes={
*       @ORM\Index(name="username_index", columns={"username"}),
*       @ORM\Index(name="email_index", columns={"email"}),
*       @ORM\Index(name="enabled_index", columns={"enabled"}),
*       @ORM\Index(name="last_login_index", columns={"last_login"})
*   }
*)
*/
class User extends BaseUser 
{
    /**
     * @ORM\Id
     * @ORM\Column(name="id", type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

更多信息请点击此处


注意:此方法还确保对经过身份验证的用户的流行检查
$user=$this->getUser()也不会影响您的数据库。

如果我理解正确,它是否仍将加入联系人表?我不想要额外的连接,因为联系人id在用户表上。不,但是现在我知道你需要什么,我的解决方案不能解决你的问题,所以我假设是一个oneToone关系,尝试在它上面添加FETCH=EAGER指令
FETCH=“EAGER”
希望这有助于你基本上不能,至少在没有一些黑客的情况下不能。条令2的对象关系管理器处理对象,而不是ID。我知道这是一个概念性的步骤,额外的连接可能看起来很麻烦,但是按照设计的方式使用它。如果仍然存在问题,请下拉到数据库访问层并使用sql。谢谢。这是一个很好的特点。在我当前的项目中,我无法使用,因为web应用程序运行在访问同一db服务器的不同服务器上。因此,当更新另一台服务器上的实体时,缓存过期将不起作用。那么您应该使用分布式缓存,如redis或memcache。对于二级缓存,通过实体管理器对实体进行的任何更新都会自动更新缓存,无论是本地缓存还是分布式缓存:)
    orm:
        auto_generate_proxy_classes: "%kernel.debug%"
        entity_managers:
            default:
                connection: default
                auto_mapping: true
                naming_strategy: doctrine.orm.naming_strategy.underscore
                second_level_cache:
                    enabled:            true
#                    region_lock_lifetime: 60
                    region_lifetime:    300
                    log_enabled:        %kernel.debug%
                    region_cache_driver: apc
                    regions: 
                        users_region: 
                            region_lifetime:    2592000
                            region_cache_driver: apc