简体   繁体   English

更新学说中的多对多关系

[英]Update a many-to-many relationship in Doctrine

I have an article-category relationship and I'd like to update the relationship when necessary. 我有一个文章类别关系,我想在必要时更新该关系。 That means, adding or removing the desired categories from an article. 就是说,在文章中添加或删除所需的类别。 I use a php (ZF) setup with Doctrine 1.2. 我在Doctrine 1.2中使用php(ZF)设置。 In YAML, the config looks (simplified) like this: 在YAML中,配置看起来(简化)如下:

Article:
  columns:
    id: bigint(10)

Category:
  columns:
    id: bigint (10)
  relations:
    articles:
      foreignAlias: categories
      class: Article
      refClass: CategoryArticle

CategoryArticle:
  columns:
    category_id: bigint (10)
    article_id: bigint (10)
  relations:
    category:
      class: Category
      foreignAlias: categoryArticle
    article:
      class: Article
      foreignAlias: categoryArticle

I have a persisted $article where all old categories are available. 我有一个坚持的文章,其中所有旧类别均可用。 With a POST request I get a list of category ids which should be the new ones. 通过POST请求,我得到了应该为新类别ID的列表。 I have this so far: 到目前为止,我有:

$oldCategories = array();
foreach ($article->categories as $cat) {
    $oldCategories[] = $cat->id;
}
$newCategories = $form->getValue('categories');

$diffRemove = array_diff($oldCategories, $newCategories);
$diffAdd    = array_diff($newCategories, $oldCategories);
foreach ($diffRemove as $id) {
    // Remove all the categories $id from article [1]
}
foreach ($diffAdd as $id) {
    // Add all the categories $id to article [2]
}

My question is about [1] and [2]. 我的问题是关于[1]和[2]。 What is the best performance to add and remove a many:many relationship? 添加和删​​除多对多关系的最佳性能是什么?

Deletion 删除

The most efficient way of deleting en masse in SQL is using single sql statement with some conditions set, something like 删除SQL中最有效的方法是使用设置了某些条件的单个sql语句,例如

delete from Products where id>3

It make use of indexes, partitioning, etc. 它利用索引,分区等。

There is a way to achieve that value of performance using Doctrine 1.2 - using DQL DELETE statements. 有一种方法可以使用Doctrine 1.2实现该性能值-使用DQL DELETE语句。 As shown in documentation, the following query transforms into the above SQL: 如文档所示,以下查询将转换为上述SQL:

$q = Doctrine_Query::create()
    ->delete('Products p')
    ->where('p.id > 3');

In your case, you could optimize deletion with something like 在您的情况下,您可以使用以下方式优化删除操作:

$q = Doctrine_Query::create()
    ->delete('CategoryArticle ca')
    ->where('ca.article_id=?', $article_id)
    ->andWhereIn('ca.category_id', $diffRemove);

This code should generate something like: 此代码应生成如下内容:

delete from CategoryArticle 
where article_id = $article_id and category_id in ($diffremove)

Insertion 插入

With insertion you could use CategoryArticle entity. 插入后,您可以使用CategoryArticle实体。 The most effective way to do that with Doctrine is to build up a collection of Entities and than save that collecion: 使用Doctrine进行此操作最有效的方法是建立一个实体集合,然后保存该集合:

$collection = new Doctrine_Collection('CategoryArticle');
foreach ($diffAdd as $id){
    $ca = new CategoryArticle();
    $ca->category = $id;
    $ca->article = $article_id;
    $collection[] = $ca;
}

$collection->save();

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

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