0

我正在构建一个产品管理工具,其中product可以有任意数量的attributes, documents, features, images,videos以及单个type,brandcategory. 还有一些其他相关的表,但这足以说明问题。

有一个名为 Model 的类ProductModel包含这样的方法(为清楚起见而减少):

  public function loadValues() {
    //Product entity data
    $this->id = $this->entity->getId();
    $this->slug = $this->entity->getSlug();

    // One of each of these
    $this->loadType();
    $this->loadBrand();
    $this->loadCategory();

    // Arbitrary number of each of these
    $this->loadAttributes();
    $this->loadDocuments();
    $this->loadFeatures();
    $this->loadImages();
    $this->loadVideos();
    ...
  }

每个加载方法都会做一些最终执行此方法的样板:

  public function loadEntitiesByProductId($productId=0) {

    // Get all the entities of this type that are associated with the product.
    $entities = $this->entityManager
      ->getRepository($this->entityName)
      ->findByProduct($productId);

    $instances = array();

    // Create a Model for each entity and load the data.
    foreach ($entities as $entity) {
      $id = $entity->getId();
      $instances[$id] = new $this->childClass();
      $instances[$id]->entity = $entity;
      $instances[$id]->loadValues();
    }

    return $instances;

  }

这适用于相关实体是单个表的情况,但通常它是一个映射器。在这些情况下,我在第一个查询中获取所有映射器实体,然后我必须在方法中查询相关实体loadValues()(通过 Doctrine 的get<Entity>()方法)。这个过程的结果是大量的查询(通常 > 100)。我需要摆脱无关的查询,但我希望这样做不会丢失我在数据模型中使用的惯用语。

有没有办法让 entityManager 更好地使用连接对这些查询进行分组?

4

1 回答 1

1

我以前的方法有几个问题:

首先,我从存储库中获取实体,而不是从现有实体中加载它们:

$entities = $this->entityManager
  ->getRepository($this->entityName)
  ->findByProduct($productId);

更好的是:

$method = $this->deriveGetMethod($this->entityName);
$entities = $productEntity->$method()

其次,我正在检索产品实体,使用$this->entityManager->getRespository...它可以很好地加载小型数据集(单个表或一个或两个关系),但是没有办法让存储库的findBy方法在单个查询中加载关系。解决方案是使用 queryBuilder。

$qb = $this->entityManger->createQueryBuilder();
$query = $this->select('product',/*related tables*/)->/*joins etc.*/
$productEntity = $query->getSingleResult();
于 2013-07-26T15:08:13.380 回答