Shopware:如何在产品实体中关联多对多表的附加数据
解决Shopware版本化实体多对多关联附加数据的查询问题
针对你的场景,直接使用ManyToManyAssociationField无法自动处理版本化实体的version_id关联条件——默认字段解析器只会匹配实体主ID,不会自动带上版本ID的过滤规则。可以通过以下两种方式解决:
方案一:拆分关联(推荐,符合Shopware核心规范)
放弃直接多对多关联,改成从Product到中间表MyProductCategoryDefinition的一对多关联,再通过中间表关联到Category:
- 修改ProductDefinition的扩展代码
public function extendFields(FieldCollection $collection): void { $collection->add( new OneToManyAssociationField( 'productCategoryData', MyProductCategoryDefinition::class, 'product_id', 'id' )->addFlags(new ApiAware(), new CascadeDelete(false)) ); }
- 在查询时关联完整数据
在sales_channel.product.process.criteria事件中,通过嵌套关联获取分类及附加数据:
// 关联中间表和分类 $criteria->addAssociation('productCategoryData.category'); // 如需过滤特定版本的分类,添加对应规则 $criteria->getAssociation('productCategoryData') ->addFilter(new EqualsFilter('category_version_id', $event->getContext()->getVersionId()));
这种方式会自动生成符合预期的SQL逻辑:
- 左连接中间表时,自动匹配
product.id = product_category_data.product_id和product.version_id = product_category_data.product_version_id - 关联分类时,匹配
category.id = product_category_data.category_id和category.version_id = product_category_data.category_version_id
方案二:自定义关联字段解析器(复杂场景可选)
如果必须保留类似product.categoriesRo的直接多对多关联形式,需要自定义AssociationField和对应的FieldResolver,参考核心的OneToManyAssociationFieldResolver实现,在解析过程中手动添加版本ID的关联条件。不过这种方式需要深入Shopware DAL底层,复杂度较高,非必要不推荐。
Shopware核心中的类似场景(如sales_channel_payment_method)均采用方案一的拆分关联方式,通过一对多关联中间表再关联目标实体,来处理版本化实体的附加数据存储与查询。
内容的提问来源于stack exchange,提问作者ts-mothership
相关产品推荐
相关产品推荐

