Php 学说导致实体缺失

Php 学说导致实体缺失,php,doctrine-orm,Php,Doctrine Orm,我想弄清楚这件事已经有一段时间了。让我们从基本信息开始,我有一个客户表和一个联系人表。客户机表与contact具有OneToMany和OneToOne关系 class Client { /** * @var int * @Id * @Column(type="integer", nullable=false, unique=true, options={"comment":"Auto incrementing client_id of each clie

我想弄清楚这件事已经有一段时间了。让我们从基本信息开始,我有一个客户表和一个联系人表。客户机表与contact具有OneToMany和OneToOne关系

class Client
{
     /**
     * @var int
     * @Id 
     * @Column(type="integer", nullable=false, unique=true, options={"comment":"Auto incrementing client_id of each client"}) 
     * @GeneratedValue
     */
     protected $pid;

     /**
     * @OneToMany(targetEntity="Contact", mappedBy="client")
     * @JoinColumn(name="contact_id", referencedColumnName="pid")
     * @var Contact[]
     */
     protected $contact;

    /**
     * @OneToOne(targetEntity="Contact")
     * @JoinColumn(name="defaultcontact_id", referencedColumnName="pid", nullable=true)
     * @var Contact
     */
    protected $default_contact;
联系人表与客户端有多通关系:

class Contact
{
    /**
     * @var int
     * @Id 
     * @Column(type="integer", nullable=false, unique=true, options={"comment":"Auto incrementing user_id of each user"}) 
     * @GeneratedValue
     */
    protected $pid;

    /**
     * @ManyToOne(targetEntity="Client", inversedBy="contact")
     * @JoinColumn(name="client_id", referencedColumnName="pid")
     */
    protected $client;
以下是我一直使用的查询:

    $qb = $entityManager->createQueryBuilder();

    $qb->select("cn as contact", "cl as client")
        ->from('DB\Contact', 'cn')
        ->innerJoin('cn.client', 'cl')
        ->where(
            $qb->expr()->andX(
                $qb->expr()->eq('cl.client_name', '?1'),
                $qb->expr()->eq('cn.pid', '?2')
            )
        )
        ->setParameter(1, $client)
        ->setParameter(2, $contact);

    try
    {
        $result = $qb->getQuery()->getOneOrNullResult();
    }
我要联系人和客户。这就是我遇到的问题:array_keys$result最终输出:

Array
(
    [0] => contact
)
我想要这样的东西:

[0] => contact
[1] => client
换句话说,缺少客户机实体。将选择从联系人切换到客户端存储库会产生相反的情况,联系人丢失

我已经检查了前面的代码,虽然entityManager在登录步骤中被重用,但这是第一次访问客户机和联系人存储库,所以我认为这不是缓存问题

下面是正在执行的SQL语句:

Executing SQL: 
SELECT c0_.pid AS pid0, c0_.caller AS caller1, c0_.address_1 AS address_12, c0_.address_2 AS address_23, 
c0_.unit AS unit4, c0_.city AS city5, c0_.state AS state6, c0_.zip_code AS zip_code7, c0_.phone AS phone8, 
c0_.email AS email9, c0_.is_active AS is_active10, c0_.date_created AS date_created11, 
c0_.date_last_modified AS date_last_modified12, c1_.pid AS pid13, c1_.client_name AS client_name14, 
c1_.is_active AS is_active15, c1_.date_created AS date_created16, c1_.date_last_modified AS date_last_modified17, 
c0_.client_id AS client_id18, c0_.created_by_id AS created_by_id19, c0_.last_modified_by_id AS last_modified_by_id20, 
c1_.defaultcontact_id AS defaultcontact_id21, c1_.created_by_id AS created_by_id22, 
c1_.last_modified_by_id AS last_modified_by_id23 
FROM contacts c0_ 
INNER JOIN clients c1_ ON c0_.client_id = c1_.pid 
WHERE c1_.client_name= ? AND c0_.pid = ?
作为旁注,如果我更改select,使缺少的实体访问特定列,我将获得所需的值

e、 g

将具有以下数组\u keys$result:

Array
(
    [0] => contact
    [1] => client
)
因此,我可以向您保证,客户机确实存在于数据库中,并且应该正确地连接到联系人,只是在第一个select语句下,我想要整个实体,而不仅仅是一列,实体最终不会被推送到结果数组中


为什么会这样?Sql语句中的列是否太多?我是否忘记了注释中的某些内容?

首先:结果数组中不能有不同的实体:结果中的每一行必须采用相同的格式

第二:如果仔细检查SQL查询,您会注意到返回的一行同时包含联系人c0_uu和客户机c1_u。
尝试在数据库中执行SQL查询以查看结果。

在查看了一系列堆栈溢出问题后,我得出了以下结论:doctrine似乎就是这样处理Fetch连接的

大线索来自这里:

支持这种行为存在的证据来自:

更具体地说,条令文件中的这句话开始有意义了:

当使用fetch join查询时,它将返回中的类 结果数组根级别上的FROM子句。在过去 示例返回一个用户实例数组以及每个实例的地址 用户被提取并水合到Useraddress变量中。如果你 访问地址原则不需要延迟加载关联 还有一个问题

用外行的话说,在获取连接过程中,如果从客户机存储库中选择,则联系人或客户机被指定为根实体。为客户机找到的任何内容都将被推入联系人的$Client变量中,然后使用getter访问器进行检索

检索本身不需要后续数据库查询来获取客户机实体。我需要做一些测试,但看起来这种行为是针对在连接过程中返回多个结果的情况。结果不是杂乱无章的,而是根据直观的位置进行组织

换言之,我有错误的期望,并在错误的地点寻找。客户实体确实回来了,但没有放在结果中。这是根据合同提交的。因此,单独检索它是给定的,但至少不需要另一个数据库调用


至少现在,我相信我知道了为什么当我在“发件人”字段中有客户时,当我尝试使用getContact访问器时,我得到的是一个特定联系人而不是所有联系人。

我不确定第二个联系人是否相关,但第一个似乎是一个很有希望的潜在客户。有证据吗?因为官方文档中有这样一个例子:$query=$em->createQuerySELECT u,一个FROM用户u JOIN u.address a WHERE a.city='Berlin';它也在选择多个实体。没错,但这是连接的一般工作方式。结果将是array 0=>array contactfields,clientfields,而不是所需的array 0=>contact,1=>client
Array
(
    [0] => contact
    [1] => client
)