【问题标题】:PHP Symfony + One-to-Many Relationship + Result CachingPHP Symfony + 一对多关系 + 结果缓存
【发布时间】:2010-06-09 19:02:32
【问题描述】:

在使用 Symfony 1.4 定义一对多关系时,我遇到了意想不到的行为(对我来说!)。这是一个演示行为的简单示例,有一个 Employer 表和一个 Employee 表:一个 Employer 可以有多个 Employees。 YML架构文件如下:

Employee:
  columns:
    id: { type: integer, primary: true, autoincrement: true }
    first_name: { type: string(30), notnull: true }
    last_name: { type: string(30), notnull: true }
    employer_id: { type: integer }
  relations:
    Employer:
      local: employer_id
      foreign: id
      type: one
      foreignType: many
      foreignAlias: Workers

Employer:
  columns:
    id: { type: integer, primary: true, autoincrement: true }
    name: { type: string(100) }
    line1: { type: string(100) }
    city: { type: string(100) }
    state: { type: string(10) }

因此,在 Employer 上调用 getWorkers() 应该返回与 Employer 关联的员工。当getWorkers() 第一次被调用时,我得到了这个预期的行为。

但是,在后续调用中,如果已向雇主添加了额外的员工(以编程方式或直接在数据库 [MySQL] 中),getWorkers() 调用仍会返回第一个结果。

我已通过单步执行 getWorkers() 调用的 Symfony 源来验证,在后续调用中,它会返回存储在 _references 数组中的缓存值。

如果我以编程方式跟踪外键,通过employee_id 查询Employee,那么我会得到完整的结果集。

谁能解释这种行为?

这是我在“动作”中运行的一些示例 PHP 代码,它演示了行为:

// Create common employer.
$employer = new Employer();
$employer->setName("My Employer");
$employer->setLine1("100 Main Street");
$employer->setCity("AnyTown");
$employer->setState("State");
$employer->save();

// Create two employees,
$worker1 = new Employee();
$worker1->setFirstName("John");
$worker1->setLastName("Doe");
$worker1->setEmployer($employer);
$worker1->save();

$worker2 = new Employee();
$worker2->setFirstName("Jane");
$worker2->setLastName("Smith");
$worker2->setEmployer($employer);
$worker2->save();

$myEmployer = Doctrine_Core::getTable('Employer')->findOneBy('name', 'My Employer');
$workers = $myEmployer->getWorkers();
echo "Number of workers for " . $myEmployer->getName() . ' is ' . count($workers);
// This gives the expected 2 employees.

// Now create another employee in the common employer.
$worker3 = new Employee();
$worker3->setFirstName("Anne");
$worker3->setLastName("Droid");
$worker3->setEmployer($employer);
$worker3->save();

$myEmployer = Doctrine_Core::getTable('Employer')->findOneBy('name', 'My Employer');
$workers = $myEmployer->getWorkers();
echo "Number of workers for " . $myEmployer->getName() . ' is ' . count($workers);
// This still gives 2 employees, whereas there are 3 in the DB.

// Follow FK directly.
$workers = Doctrine_Core::getTable('Employee')->findBy('employer_id', $myEmployer->getId());
echo "Number of workers for " . $myEmployer->getName() . ' is ' . count($workers);
// This gives the expected 3 employees.

如何强制它每次都重新关注关系?

【问题讨论】:

    标签: php caching symfony1 one-to-many symfony-1.4


    【解决方案1】:

    添加新的相关记录时,您可能需要刷新记录的关系。

    你可以做任何一个:

    $worker->refresh(true);
    $worker->refreshRelated();
    $worker->refreshRelated('Employer');
    

    有关更多信息,您应该检查以下内容: Doctrine Documentation - Refreshing Relationships

    【讨论】:

    • 非常感谢。效果很好!在 ORM 中是否经常需要显式调用以将对象与数据库同步?我最初的反应是,除非我另有说明,否则我希望选项/默认值始终从数据库中获取/同步。如果没有,每次您认为某些代码/进程可能已更新相关数据时,您必须记住插入“刷新”调用。在显式调用 save() 之后,我可以看到这样做的一些价值,但是对于那些也独立于 ORM 框架(例如通过外部提要)填充的数据呢?
    猜你喜欢
    • 2017-03-27
    • 2015-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-22
    • 2012-03-03
    • 2019-06-28
    • 1970-01-01
    相关资源
    最近更新 更多