简体   繁体   English

根据多种条件从联接中选择原则

[英]Doctrine selecting from joins based on multiple conditions

I am trying to make a selection based on multiple ids in joins, each of the ids should match another condition of another join. 我试图基于联接中的多个ID进行选择,每个ID应匹配另一个联接的另一个条件。

I need to get "Types" that have all the "Dichotomies" in "Position" 1 or 2. At the moment it gives me results that match one of the Dichotomies passed to the function, but not all of them. 我需要获取在“位置” 1或2中具有所有“二分法”的“类型”。此刻,它给我的结果与传递给函数的二分法之一匹配,但不是全部。

$QB->select("Types","Types,ElementsPositions, Elements, Positions, Dichotomies, Quadras,TypesDescriptions,Relations")
                ->from($this->get_repository()[0], 'Types');
                $QB->leftJoin("Types.ElementsPositions","ElementsPositions", \Doctrine\ORM\Query\Expr\Join::WITH, 'ElementsPositions.Positions = 1 OR ElementsPositions.Positions = 2');
                $QB->leftJoin("ElementsPositions.Elements","Elements");
                $QB->leftJoin("ElementsPositions.Positions","Positions");
                $QB->leftJoin("Elements.Dichotomies","Dichotomies");
                $QB->leftJoin("Types.Quadras","Quadras");
                $QB->leftJoin("Types.TypesDescriptions","TypesDescriptions");
                $QB->leftJoin("Types.Relations","Relations");

    if(!empty($where['dichotomies'])){
        foreach($where['dichotomies'] as $dichotomy){
                $QB->andWhere('Dichotomies.id'.'=:dichotomy');
                $QB->setParameter('dichotomy', $dichotomy['id']);                
        }            
    }

UPD. UPD。 Tables mapping - in JSON: 表映射-在JSON中:

{
"table-name": "types",    
"joins":[
    {
        "table-name":"elements_positions",
        "type":"one-to-many"
    },
    {
        "table-name":"quadras",
        "type":"many-to-one"
    },
    {
        "table-name":"types_descriptions",
        "type":"one-to-one"
    },
    {
        "table-name":"relations",
        "type":"many-to-one"
    }
]}

Elements Positions 元素位置

{
    "table-name": "elements_positions",
    "joins":[
        {
            "table-name":"elements",
            "type":"many-to-one"
        },
        {
            "table-name":"positions",
            "type":"many-to-one"
        },
        {
            "table-name":"types",
            "type":"many-to-one"
        }
    ]
}

Elements 元素

 {
        "table-name": "elements",    
        "joins":[
            {
                "table-name":"elements_positions",
                "type":"one-to-many"
            },
            {
                "table-name":"quadras",
                "type":"many-to-many"
            },
            {
                "table-name":"dichotomies",
                "type":"many-to-many"
            }
        ]
    }

Positions 职位

    "table-name": "positions",    
    "joins":[
        {
            "table-name":"elements_positions",
            "type":"one-to-many"
        }
    ]
}

Dichotomies: 二分法:

{
    "table-name": "dichotomies",
    "joins":[
        {
            "table-name":"elements",
            "type":"many-to-many-inversed"
        }
    ]
}

Your query has a two different problems. 您的查询有两个不同的问题。

First, multiple parameter values are bound with single parameter. 首先,多个参数值与单个参数绑定。 Every next element of $where['dichotomies'] replaces previous value of parameter :dichotomy in the query. $where['dichotomies']每个下一个元素替换查询中参数:dichotomy先前值。 The method setParameters() don't really binds values to the prepared statement: it just stores them in QueryBuilder object. setParameters()方法实际上并不将值绑定到准备好的语句:它只是将它们存储在QueryBuilder对象中。 So, after the end of foreach-loop all conditions will be use the same value (the last of $where['dichotomies'] ). 因此,在foreach循环结束之后,所有条件都将使用相同的值( $where['dichotomies']的最后一个)。 To avoid that you need to use different parameter names or numeric indexes. 为避免这种情况,您需要使用不同的参数名称或数字索引。

Second, you add conditions that are contradictory: $QB->andWhere() will produce something like that: 其次,添加矛盾的条件: $QB->andWhere()将产生类似的结果:

Dichotomies.id = :dichotomy 
AND Dichotomies.id = :dichotomy 
AND Dichotomies.id = :dichotomy 
...

One entity ID obviously cannot be equal to different values simultaneously. 一个实体ID显然不能同时等于不同的值。 So, you need to replace AND by the OR operator. 因此,您需要用OR运算符替换AND

But better way is to use IN clause: 但是更好的方法是使用IN子句:

Calling setParameter() automatically infers which type you are setting as value. 调用setParameter()自动推断您要设置为值的类型。 This works for integers, arrays of strings/integers , DateTime instances and for managed entities. 这适用于整数, 字符串/整数数组 ,DateTime实例以及受管实体。

Just replace the foreach-loop by the following lines: 只需用以下几行替换foreach循环:

$QB->andWhere('Dichotomies.id IN (:dichotomies)');
$QB->setParameters('dichotomies', array_column($where['dichotomies'], 'id'));

The array_column() function returns a list of IDs of all dichotomies. array_column()函数返回所有二分法的ID列表。 Doctrine generates IN expression and uses that list to generate query placeholders and bind the values. Doctrine生成IN表达式,并使用该列表生成查询占位符并绑定值。

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

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