在Propel中使用EAV模型

时间:2013-03-28 11:39:08

标签: php mysql orm propel entity-attribute-value

我有一个带有EAV结构的数据库,有这个表:

Entity (id, name)
Attribute (id, name)
AttributeValue(fk_id_entity, fk_id_attribute, value)

我想要做的是在Propel中翻译以下查询:

SELECT entity.name, avx.value, avy.value
FROM Entity entity
INNER JOIN AttributeValue avx ON (avx.fk_id_entity = entity.id 
AND avx.name = 'X')
INNER JOIN AttributeValue avy ON (avy.fk_id_entity = entity.id 
AND avy.name = 'Y')

我知道怎么能在Popel做到这一点? 谢谢!

LE:意思是每个实体都有两个属性X和Y,我想显示所有实体的列表及其X和Y属性。

2 个答案:

答案 0 :(得分:2)

所以这里只是复制SQL中的内容的一种方法,但正如我在评论中提到的那样,可能有更有效的方法来实现它。如果您提供上述评论问题的答案,我会看看我是否可以改进这个答案。

首先,您的架构中需要cross reference table。我假设你这样做,并且它被称为AttributeValue。然后将联接添加到EntityQuery并添加其他条件。

不幸的是,看起来Propel中可能存在一个错误,会阻止下面的代码生成正确的SQL。

$results = EntityQuery::create()
  ->join('Entity.AttributeValue avx')
  ->join('avx.Attribute xa')
  ->addJoinCondition('xa', 'xa.name = ?', 'X')
  ->join('Entity.AttributeValue avy')
  ->join('avy.Attribute ya')
  ->addJoinCondition('ya', 'ya.name = ?', 'Y')
  ->select(array('entity.name', 'avx.value', 'avy.value'));

应该生成以下SQL:

SELECT entity.name AS 'entity.name', 
       avx.value AS 'avx.value', 
       avy.value AS 'avy.value'
  FROM `entity` 
    INNER JOIN `attribute_value` `avx` ON (entity.id = avx.entity_id) 
    INNER JOIN `attribute` `ax` ON (avx.attribute_id = ax.id AND ax.name =  'X') 
    INNER JOIN `attribute_value` `avy` ON (entity.id = avy.entity_id) 
    INNER JOIN `attribute` `ay` ON (avy.attribute_id = ay.id AND ay.name =  'Y') 

不幸的是,这是产生的:

SELECT entity.name AS 'entity.name', 
       aatribute_value.value AS 'avx.value', 
       aatribute_value.value AS 'avx.value'
  FROM `entity` 
    INNER JOIN `attribute_value` `avx` ON (entity.id = avx.entity_id) 
    INNER JOIN `attribute` `ax` ON (avx.attribute_id = ax.id AND attribute.name =  'X') 
    INNER JOIN `attribute_value` `avy` ON (entity.id = avy.entity_id) 
    INNER JOIN `attribute` `ay` ON (avy.attribute_id = ay.id AND attribute.name =  'Y') 

(问题是SELECT行和INNER JOIN attribute使用attribute.name = 'X'代替正确的ax.name = 'X'

因此,您可以使用手动查询运行正确 SQL,或者等待修复错误(我会尝试编写issue on guthub并处理修复。)

抱歉,我无法提供更多帮助。

Propel documentation on joining tables收集的信息。

答案 1 :(得分:0)

实际工作的内容如下:

$result = Entity_EntityQuery::create()
->withColumn('alias1.value', 'xvalue')
->withColumn('alias2.value', 'yvalue')
->innerjoinValue('alias1')
->useValueQuery('alias1')
->filterbyFkAttribute('x attribute id')
->endUse()
->innerjoinValue('alias1')
->useValueQuery('alias1')
->filterbyFkAttribute('y attribute id')
->endUse()
...//conditions
->find()

感谢大家的观看和回复!