简体   繁体   English

TYPO3 Extbase连接

[英]TYPO3 Extbase Join

I'm try to make this query with extbase work: 我试图使这个查询与extbase一起工作:

SELECT a.* 
  FROM tx_apartments_domain_model_apartment a 
  LEFT 
  JOIN tx_apartments_domain_model_booking b 
    ON b.apartment = a.uid 
   AND b.start <= '2018-07-23' 
   AND b.end >= '2018-07-21'
 WHERE b.uid IS NULL AND a.hidden=0 AND a.deleted=0;

the following code does not work, i get an empty result: 以下代码不起作用,我得到一个空结果:

    /** @var QueryBuilder $queryBuilder */
    $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
        ->getQueryBuilderForTable('tx_apartments_domain_model_apartment');
    $statement = $queryBuilder
        ->select('a.*')
        ->from('tx_apartments_domain_model_apartment','a')
        ->leftJoin(
            'a',
            'tx_apartments_domain_model_booking',
            'b',
            $queryBuilder->expr()->andX(
                $queryBuilder->expr()->eq('b.apartment','a.uid'),
                $queryBuilder->expr()->lte('b.start', '2018-07-23'),
                $queryBuilder->expr()->gte('b.end', '2018-07-21')
            )
        )
        ->where(
            $queryBuilder->expr()->isNull('b.uid')
        )
        ->execute();
    //DebuggerUtility::var_dump($queryBuilder->getSQL());
    return $statement->fetchAll();

can anybody help me? 有谁能够帮助我?

What kind of records do you expect to get? 您希望获得什么样的记录?

as uid is a mandantory field you never have records where the uid is NULL. 因为uid是必填字段,所以您永远不会有uid为NULL的记录。

If you want to access new records which are not stored to the database yet: they get a faked uid like NEW123 如果要访问尚未存储到数据库的新记录:它们会得到伪造的uid,例如NEW123

This works for me: 这对我有用:

        /** @var QueryBuilder $queryBuilder */
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
            ->getQueryBuilderForTable('tx_apartments_domain_model_apartment');

        $queryBuilder
            ->getRestrictions()
            ->removeAll();

        $statement = $queryBuilder
            ->select('a.*')
            ->from('tx_apartments_domain_model_apartment','a')
            ->leftJoin(
                'a',
                'tx_apartments_domain_model_booking',
                'b',
                $queryBuilder->expr()->andX(
                    $queryBuilder->expr()->eq('b.apartment','a.uid'),
                    $queryBuilder->expr()->lte('b.start', $queryBuilder->createNamedParameter('2018-07-23')),
                    $queryBuilder->expr()->gte('b.end', $queryBuilder->createNamedParameter('2018-07-21'))
                )
            )
            ->where(
                $queryBuilder->expr()->andX(
                    $queryBuilder->expr()->isNull('b.uid'),
                    $queryBuilder->expr()->eq('a.hidden',0),
                    $queryBuilder->expr()->eq('a.deleted',0)
                )
            )
            ->execute();
        $results = $statement->fetchAll();
//        DebuggerUtility::var_dump($queryBuilder->getSQL());
//        DebuggerUtility::var_dump($results);
        return $results;

I do not know where exactly you are using this code. 我不知道您到底在哪里使用此代码。 Typically I would think that retrieving records from the database should happen in a repository. 通常,我认为从数据库检索记录应该在存储库中进行。

If you are using this in the ApartmentRepository and if there is a relation properly configured between apartments and bookings (1:n, I would assume) in the TCA, then you could use something like this: 如果您在ApartmentRepository中使用此功能,并且在TCA中在公寓和预订之间正确配置了一种关系(我认为是1:n),那么您可以使用以下方式:

public function findInDateRange ($dateConstraint) 
{
    $query = $this->createQuery();
    $constraints = [];
    $constraints[] = $query->lessThanOrEqual(
        'bookings.start',
        $dateConstraint['start']
    );
    $constraints[] = $query->greaterThanOrEqual(
        'bookings.end',
        $dateConstraint['end']
    );

    $query->matching($query->logicalAnd($constraints));
    return $query->execute();
}

I deliberately left out the b.uid IS NULL part here, as that should always return nothing since uid should be AUTO_INCREMENT . 我在这里故意省略了b.uid IS NULL部分,因为uid应该是AUTO_INCREMENT所以它应该始终不返回任何内容。 Unless the default query settings are changed, there is also no need to check the disable fields (hidden, deleted) manually. 除非更改了默认查询设置,否则也无需手动检查禁用字段(隐藏,删除)。

Note that in order for this to work, the Apartment Domain Model needs a field bookings with a corresponding column in the database (that is something I stumbled over last year). 请注意,为了使它起作用,Apartment Domain Model需要在数据库中具有相应列的字段预订(这是我去年偶然发现的)。

As a side-note: Is it intentional that you allow for the end to be before the start in your query (start: 2018-07-23, end: 2018-07-21), or is that just exemplary? 附带说明:您是否故意在查询的开始之前允许结束(开始:2018-07-23,结束:2018-07-21),还是仅作为示例?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM