CakePHP3使用主键(setPrimaryKey)进行连接,即使I';我指定了一个外键

CakePHP3使用主键(setPrimaryKey)进行连接,即使I';我指定了一个外键,php,cakephp,cakephp-3.x,Php,Cakephp,Cakephp 3.x,CakePHP3.7 我有两个模型表类,如下所示: /src/Model/Table/SubstancesTable.php /src/Model/Table/tblorganizationsubstancestable.php MySQL中每个表的架构如下所示: 一, 二, 我已经编写了一个自定义查找程序,它需要在这两个表之间执行连接。自定义查找程序如下所示,位于SubstancesTable.php: public function findDistinctSubstancesByOrgan

CakePHP3.7

我有两个模型表类,如下所示:

  • /src/Model/Table/SubstancesTable.php
  • /src/Model/Table/tblorganizationsubstancestable.php
  • MySQL中每个表的架构如下所示:

    一,

    二,

    我已经编写了一个自定义查找程序,它需要在这两个表之间执行
    连接。自定义查找程序如下所示,位于
    SubstancesTable.php

    public function findDistinctSubstancesByOrganisation(Query $query, array $options)
    {
        $o_id = $options['o_id'];
    
        $query = $this->find()->select('id')->contain('TblOrganisationSubstances')->where(['TblOrganisationSubstances.o_id' => $o_id]);
    
        return $query;
    }
    
    每个表都有一个
    app_id
    列,这是链接这两个表的外键

    起初,我遇到了一个错误:

    未对物质进行定义

    这是有道理的,因为没有任何定义

    因此,在
    SubstancesTable.php
    中,我定义了:

    $this->setPrimaryKey('id');
    
    // ...
    
    $this->belongsTo('TblOrganisationSubstances', [
        'foreignKey' => 'app_id',
        'joinType' => 'INNER'
    ]);
    
    但这将生成以下SQL语句:

    SELECT Substances.id AS `Substances__id` FROM substances Substances INNER JOIN tbl_organisation_substances TblOrganisationSubstances ON TblOrganisationSubstances.o_sub_id = (Substances.app_id) WHERE TblOrganisationSubstances.o_id = :c0
    
    这是行不通的,因为
    tblorganizationsubstances.o_sub_id=(Substances.app_id)
    是错误的。它需要基于
    app\u id
    加入,换句话说,它应该是:

    TblOrganisationSubstances.app_id = (Substances.app_id)
    
    我还尝试将
    belongsTo
    更改为
    有许多关联(甚至不确定哪一个在这里!):

    但这种加入似乎根本没有发生。生成的SQL是:

    SELECT Substances.id AS `Substances__id` FROM substances Substances WHERE TblOrganisationSubstances.o_id = :c0
    
    我还尝试在
    tblorganizationsubstances.php
    中放置
    belongsTo
    ,尝试从双方定义关系:

    $this->belongsTo('Substances', [
        'foreignKey' => 'app_id',
        'joinType' => 'INNER'
    ]);
    
    再说一次,这是行不通的。它生成不带连接的SQL


    请有人帮助建议哪种类型的关联是正确的(
    hasMany
    vs
    belongsTo
    ),以及如何基于
    app\u id
    (链接两个表的外键)执行连接。

    belongsTo
    关联中,源表保存外键,因此,在您的配置中,它将在
    物质上使用
    app\u id
    ,并与
    tblororganizationsubstances
    的主键进行比较

    为了获得要查找的查询,还必须定义
    bindingKey
    ,即目标表的外键,以便它不使用主键:

    $this->belongsTo('tblorganizationsubstances'[
    'foreignKey'=>'app_id',//Substances.app_id
    'bindingKey'=>'app_id',//tblorganizationsubstances.app_id
    “joinType”=>“内部”
    ]);
    
    无论是
    有许多
    还是
    属于
    ,都取决于您的数据,以及您想要检索的内容和方式。通常,如果一种
    物质
    有0或1种
    t氯组织物质
    1:1
    ),那么它就
    属于
    有一种
    。如果一种
    物质
    可以有多个
    t氯组织物质
    1:n
    ),那么它的
    就有很多

    如果要按
    具有多个关联进行筛选,则需要使用匹配或联接(
    matching()
    innerJoinWith()
    leftJoinWith()
    ),因为使用
    包含()
    时,
    具有多个关联记录将在单独的查询中检索

    另见


    样本
    左连接
    用户
    样本
    rac\u id
    用户
    用户
    用户rac\u id
    联合所有选择*这是一个演示示例,通过它可以帮助您明确内部连接的概念,并创建您自己的代码。有两个表sample和user,我尝试在sql查询中应用innerjoin这与问题无关,也不使用问题中给出的任何等效表。这与问题无关,也不使用问题中给出的任何等效表。
        public $hasAndBelongsToMany = array(
            'Ingredient' =>
                array(
                    'className' => 'Ingredient',
                    'joinTable' => 'ingredients_recipes',
                    'foreignKey' => 'recipe_id',
                    'associationForeignKey' => 'ingredient_id',
                    'unique' => true,
                    'conditions' => '',
                    'fields' => '',
                    'order' => '',
                    'limit' => '',
                    'offset' => '',
                    'finderQuery' => '',
                    'with' => ''
                )
        );
    }````
    
    SELECT Substances.id AS `Substances__id` FROM substances Substances WHERE TblOrganisationSubstances.o_id = :c0
    
    $this->belongsTo('Substances', [
        'foreignKey' => 'app_id',
        'joinType' => 'INNER'
    ]);
    
        public $hasAndBelongsToMany = array(
            'Ingredient' =>
                array(
                    'className' => 'Ingredient',
                    'joinTable' => 'ingredients_recipes',
                    'foreignKey' => 'recipe_id',
                    'associationForeignKey' => 'ingredient_id',
                    'unique' => true,
                    'conditions' => '',
                    'fields' => '',
                    'order' => '',
                    'limit' => '',
                    'offset' => '',
                    'finderQuery' => '',
                    'with' => ''
                )
        );
    }````